0

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);
        });
      })

    }

})
5
  • What is T ...? Commented Jan 17, 2018 at 13:38
  • T is the twit lib. I've updated my question with extra information Commented Jan 17, 2018 at 13:41
  • That module says you can use cb and promises at the same time, but I don't really know why you would... Commented Jan 17, 2018 at 13:43
  • I don't understand your comment. I'm trying to wait for the translation api to return the results before sending all the data to the front end side of my app. Commented Jan 17, 2018 at 13:46
  • oh duh I realize what you're doing wrong now Commented Jan 17, 2018 at 13:48

2 Answers 2

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);
    }
});
Sign up to request clarification or add additional context in comments.

3 Comments

it seems that the log 'ALL PROMISES DONE' is not event fired when doing this adjustment
that means there is a problem while executing the callback ;) Try to put breakpoints inside the callback or console.log at every step to see where it goes wrong. Also check what the response of the sent request
my bad, I have a condition within my sentiment analysis which prevent from resolving text with negative sentiment. All my tweets were scored with "-1" so nothing was happening. Without this condition everything is working properly! answer accepted. thanks!
0

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);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.