skip to Main Content

I’m facing a little issue using promises in a for loop within a node script

I’m first calling data from a twitter search, and I want to translate all tweets from english to french before sending the results to the front end of my application. It seems that my current model isn’t working as promises.all() console.log(‘ALL PROMISES DONE’) is firing right from the strart when triggering the T.get() function. any advice?

var Twit = require('twit')
var T = new Twit({
  consumer_key: '...',  
  consumer_secret: '...',
  access_token: '...',  
  access_token_secret: '...',
  timeout_ms:           60*1000,  // optional HTTP request timeout to apply to all requests. 
})

//TWITTER
app.post('/twitter/search/hashtags', function (req, res) {

  // TWITTER QUERY PARAMS
  var params = {
    q: req.body.search,
    count: 2,
    //lang: 'fr'
  }

  //GData
  var bloc = [];
  var promises = [];

  // TWITTER API GET INFORMATION
  T.get('search/tweets', params, function(err, data, response) {
      // if there no errors
        if (!err) {
            //PROCESSING DATA FROM TWITTER

            if(data){

              for(var i= 0; i < data.statuses.length; i++){
                //translate all text string which are not in french
                var lang = data.statuses[i].lang;
                var str = data.statuses[i].text;
                if(lang != "fr"){
                  promises.push(translate_str(data.statuses[i].user.screen_name, str, lang));
                }
              }
            }
            //res.send(bloc);

        }
        // if unable to Search a tweet
        else {
          console.log('Something went wrong while SEARCHING...');
          console.log(err);
        }
    }); 

    Promise.all(promises)    
     .then(function(data){ console.log("ALL PROMISES DONE"); console.log(data);/* do stuff when success */ })
     .catch(function(err){ /* error handling */ });

    //TRANSLATE
    function translate_str(name, str, lang){
      return new Promise(function(resolve, reject){
        translate(str, {from: lang, to: 'fr'}).then(res => {
            console.log('TRANSLATED INTO :');
            console.log(res.text);

            //SENTIMENT ANALYSIS
            var r1 = sentiment(res.text, 'fr');
            console.log(r1.score);
            console.log(r1.positive);
            //IF SCORE POSITIVE THEN PUSH TO FRONT
            if(r1.score > 0){
              resolve({
                name: name,
                text: res.text,
                lang: lang,
                selected: false
              })
            }
        }).catch(err => {
            console.error(err);
        });
      })

    }

})

2

Answers


  1. Well what’s happening is simply that T.get is an asynchronous function that calls a callback when it’s done, but the Promise.all part is outside the function so it gets called just after T.get() is fired, when the callback has not yet been called. Try moving it inside the callback :

    T.get('search/tweets', params, function(err, data, response) {
      // if there no errors
        if (!err) {
            //PROCESSING DATA FROM TWITTER
    
            if(data){
    
              for(var i= 0; i < data.statuses.length; i++){
                //translate all text string which are not in french
                var lang = data.statuses[i].lang;
                var str = data.statuses[i].text;
                if(lang != "fr"){
                  promises.push(translate_str(data.statuses[i].user.screen_name, str, lang));
                }
              }
              Promise.all(promises)    
                .then(function(data){ console.log("ALL PROMISES DONE"); console.log(data);/* do stuff when success */ })
                .catch(function(err){ /* error handling */ });
              }
            }
            //res.send(bloc);
        // if unable to Search a tweet
        else {
          console.log('Something went wrong while SEARCHING...');
          console.log(err);
        }
    });
    
    Login or Signup to reply.
  2. You submit the ajax request, then your program jumps to promise.all() while waiting for it, and processes but there are no promises so it happens immediately. You need to move your promise function inside of the callback or use T.get().then() like so:

    // TWITTER API GET INFORMATION
    T.get('search/tweets', params)
    .then(data => {
        for (var i = 0; i < data.statuses.length; i++) {
            //translate all text string which are not in french
            var lang = data.statuses[i].lang;
            var str = data.statuses[i].text;
            if (lang != "fr") {
                promises.push(translate_str(data.statuses[i].user.screen_name, str, lang));
            }
        }
        //res.send(bloc);
        Promise.all(promises)
            .then(function (data) { console.log("ALL PROMISES DONE"); console.log(data);/* do stuff when success */ })
            .catch(function (err) { /* error handling */ });
    }).catch(err => {
        console.log('Something went wrong while SEARCHING...');
        console.log(err);
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search