0

Multiple API calls inside loop i am making multiple API calls inside the loop, function is called inside a promise and pass data to body this part work fine, in a function a return a promise which make multiple calls to API, before proceeding to further i have to get all the result. but when i console log the result it show empty array.

    var rp = require('request-promise');
    var watchonlinemovie = []; 


 exports.db = function(body){

    return new Promise((resolve,reject)=>{




        if(body.lenght > 0)
        { 
            body.forEach(movie)
            { 
                let title = movie.title;
                title = (title.slice(0,title.indexOf('('))).trim();
                let year = movie.title; 
                year = year.slice(year.indexOf('(')+1,year.indexOf(')'));

                let call = "http://www.omdbapi.com/?t="+title+"&y="+year+"&apikey="+key2+"&plot=full";

         rp(call)
          .then((body) => {


                   let movie = JSON.parse(body);

                   watchonlinemovie.push({
                     title: movie.Title, 
                     year:movie.Year, 
                     rating:movie.Rated,
                     duration:movie.Runtime,
                     genre:movie.Genre,
                     director:movie.Director, 
                     actors:movie.Actors,
                     image:movie.Poster,
                     href:movie.link, 
                   });     
         })
         .catch(err => { 
           reject(err);
         });
            }
        }

        resolve(watchonlinemovie);
    });
}
3
  • Use Promise.all([]) make all request parallel, It'll return result once all request completed. Commented Feb 13, 2018 at 7:56
  • You have a typo in body.length. Commented Feb 13, 2018 at 8:00
  • sorry i have seen typo there are also other typo, i am removing them thanks for highlighting it. i am new to javascript and nodejs Commented Feb 13, 2018 at 8:09

2 Answers 2

1

You can use async.eachOfLimit to proceed all your lines. You can adjust the limit to do it 1 by 1 or 5 by 5, or all in parallel (don't do this if you have thousand lines).

Example with 10 by 10.

    var async = require("async");
    var rp = require('request-promise');


     exports.db = function(body){

        return new Promise((resolve,reject)=>{

            var watchonlinemovie = []; 

            // change the limit here
            // process all request with a batch of 10
            async.eachOfLimit(body, 10, function(movie, i, ecb){

                // function called for each line in body

                let title = movie.title;
                title = (title.slice(0,title.indexOf('('))).trim();
                let year = movie.title; 
                year = year.slice(year.indexOf('(')+1,year.indexOf(')'));

                let call = "http://www.omdbapi.com/?t="+title+"&y="+year+"&apikey="+key2+"&plot=full";

                rp(call)
                .then((body) => {


                   let movie = JSON.parse(body);

                   watchonlinemovie.push({
                     title: movie.Title, 
                     year:movie.Year, 
                     rating:movie.Rated,
                     duration:movie.Runtime,
                     genre:movie.Genre,
                     director:movie.Director, 
                     actors:movie.Actors,
                     image:movie.Poster,
                     href:movie.link, 
                   });

                   // proceed next movie
                   return ecb(null); 
                })
                .catch(err => { 

                    // stop the async process
                    return ecb(err);
                 });
             })

            }, function(err){

                // final callback, when all request in the body has been proceed
                if(err)
                {
                     reject(err);
                }
                else
                {
                    resolve(watchonlinemovie); 
                }
            });

        });
    }
Sign up to request clarification or add additional context in comments.

Comments

0

Here is a solution that uses promises, I added something that will not allow a promise to reject but instead create a Fail type value, you can pick them out of the results.

If you need throttling you can import the file from here.

var rp = require('request-promise');

const movieToUrl = key2 => movie => {
  const title = movie.title.slice(0, title.indexOf('(')).trim();
  const year = movie.title.slice(title.indexOf('(') + 1, title.indexOf(')'));
  let call = "http://www.omdbapi.com/?t=" + title + "&y=" + year + 
    "&apikey=" + key2 + "&plot=full";
};

const movieDataToMovieInstance = movie => ({
  title: movie.Title,
  year: movie.Year,
  rating: movie.Rated,
  duration: movie.Runtime,
  genre: movie.Genre,
  director: movie.Director,
  actors: movie.Actors,
  image: movie.Poster,
  href: movie.link,
});

const Fail = function(reason){this.reason=reason;};
const isFail = x=>(x&&x.constructor)===Fail;
const isNotFail = x=>!isFail(x);

//if you want to throttle promises like max5 active or max5 per second
//  you can use throttle library here:
//  https://github.com/amsterdamharu/lib/blob/master/src/index.js
//const max5=lib.throttle(5);//this is max 5 active connections
//const max5=throttlePeriod(5,1000);//this is max 5 per second


exports.db = function (body) {
  return Promise.all(
    body.map(
      movieToUrl(key2)//key2 comes out of nowhere
      //throttled version
      //.then(max5(rp))
      .then(rp)
      .then(movieDataToMovieInstance)
      .catch(err=>new Fail([body,err]))
    )
  );
};

//example how to use:
exports.db(someBody)
.then(
  results=>{
    const successes = results.filter(isNotFail);
    const failures = results.filter(isFail);
  }
)

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.