0
const express = require('express');
require('dotenv').config();
var Twit = require('twit');

const app = express();

app.use(express.urlencoded({extended: true}));
app.set('view engine', 'ejs');

app.listen(4000);

let api_key = process.env.api_key;
let api_secret = process.env.api_secret;
let access_token = process.env.access_token;
let access_token_secret = process.env.access_token_secret;

var T = new Twit({
  consumer_key: api_key,
  consumer_secret: api_secret,
  access_token: access_token,
  access_token_secret: access_token_secret,
  timeout_ms: 60*1000,
  strictSSL: true,
});

app.post('/displayTweet', (req, res) => {
    let handleName = req.body.handle;
    let params = {screen_name: handleName, count:10};
    T.get('statuses/user_timeline', params, function(err, tweets, res){
        if(!err){
            return tweets;
        }
        else{
            console.log(err);
        }
    })
    res.redirect('displayTweet', {tweets});
});


app.get('/', (req, res) => {
    res.render('index');
});

app.get('/displayTweet', (req, res) => {
    res.render('displayTweet');
});

app.use((req, res) => {
    res.status(404).render('404');
});

In the above code, I have written a line that returns a particular value that comes from an external source (Twitter API). The problem is that the outer function wouldn't wait for the inner function to be completed. so that it can use the returned variable. How to fix this issue?

Outer function

app.post('/displayTweet', (req, res) => {
        let handleName = req.body.handle;
        let params = {screen_name: handleName, count:10};
         
        -----inner function----- 

        res.redirect('displayTweet', {tweets});
    });

inner function

T.get('statuses/user_timeline', params, function(err, tweets, res){
        if(!err){
            return tweets;
        }
        else{
            console.log(err);
        }
    })
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – jabaa Mar 21 '23 at 09:22

1 Answers1

0

Since T.get(/*...*/) is an asynchronous task you have to await it and you can do that by creating and awaiting a new Promise. I wrapped all inside a try/catch block so that in case of error your server doesn't crash, you can handle the error in the catch block

app.post('/displayTweet', async (req, res) => {
    const { handle: handleName } = req.body
    const params = {
        screen_name: handleName,
        count: 10
    }

    try {
        const tweets = await new Promise((resolve, reject) => 
            T.get('statuses/user_timeline', params, function(err, tweets, res) {
                if(!err) resolve(tweets)
                else reject(err)
            })
        )
        res.redirect('displayTweet', { tweets });
    }
    catch(e) {
        console.error(e)
        res.end()
    }
});
eroironico
  • 1,159
  • 1
  • 15