Search code examples
javascripttwitterasync-await

Unable to retrieve returned object from an async function


I'm struggling to log a tweet function's response values to the console but no matter what I do, the object keeps returning empty even though the tweet gets posted.

const Twitter = require('twitter');
const dotenv = require('dotenv');
dotenv.config();

const client = new Twitter({
  consumer_key: process.env.TWITTER_CONSUMER_KEY_TEST,
  consumer_secret: process.env.TWITTER_CONSUMER_SECRET_TEST,
  access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY_TEST,
  access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET_TEST
});

const tweet = (message, id = '0') => {
  let postRes = {};
  let status = {};
  if(id && id.length > 4) {
    status = {
      in_reply_to_status_id: id,
      status: message,
    };
  } else {
    status = {
      status: message,
    };
  }
  client.post('statuses/update', status)
  .then((tweet, response) => {
    console.log('id', tweet.id); // Tweet body.
    console.log('id_str', tweet.id_str); // Tweet body.
    console.log('text', tweet.text); // Tweet body.
    postRes.tweet = tweet.text,
    postRes.id = tweet.id_str;
    return postRes;
  })
  .catch((error) => {
    console.log('ERR');
    throw error;
  });
  // console.log('POSTRES', postRes);
  return postRes;
};

async function msg() {
  const tweeted = await tweet('this is_a__posts_async', '');
  console.log('TWEETED', tweeted);
  console.log('MESSAGE', tweeted.tweet);
  console.log('ID', tweeted.id);
}

msg();

Here, I expect the statement console.log('TWEETED', tweeted); to return an object with two elements, the tweeted text and the posted tweet's id. However, despite having it wrapped inside of an async function, it returns empty.


Solution

  • Hmm, i think you are on the right track here, but you need to resolve the promise when the call returns successfully, like so:

    const Twitter = require('twitter');
    const dotenv = require('dotenv');
    dotenv.config();
    
    const client = new Twitter({
      consumer_key: process.env.TWITTER_CONSUMER_KEY_TEST,
      consumer_secret: process.env.TWITTER_CONSUMER_SECRET_TEST,
      access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY_TEST,
      access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET_TEST
    });
    
    const tweet = (message, id = '0') => {
      // no direct return value
      let status = {};
      if(id && id.length > 4) {
        status = {
          in_reply_to_status_id: id,
          status: message,
        };
      } else {
        status = {
          status: message,
        };
      }
      return client.post('statuses/update', status)
      .then((tweet, response) => {
        console.log('id', tweet.id); // Tweet body.
        console.log('id_str', tweet.id_str); // Tweet body.
        console.log('text', tweet.text); // Tweet body.
        postRes.tweet = tweet.text,
        postRes.id = tweet.id_str;
        // here we resolve with the successful promise to keep the chain intact
        return Promise.resolve(postRes);
      })
      .catch((error) => {
        console.log('ERR');
        throw error;
      });
    };
    
    async function msg() {
      // to handle any thrown errors use a try/catch here 
      try {
        const tweeted = await tweet('this is_a__posts_async', '');
        console.log('TWEETED', tweeted);
        console.log('MESSAGE', tweeted.tweet);
        console.log('ID', tweeted.id);
      } catch(error) {
        console.log(`Error during post: ${error}`);
      }
    }
    
    msg();
    

    Hope this help!