Search code examples
apiexpressasynchronouspromisebluebird

using bluebird promises with express to make API calls


I'm trying to get different chunks of data from a trello API using bluebird promises library. In my express router I'm using middleware isLoggedIn, and getBoards, which body looks something like:

trello.get("/1/members/me/boards") // resolves with array of board objects
 .each((board) => {
  // do some async stuff like saving board to db or other api calls, based on retrieved board
 .catch(err => console.error('ERR: fetching boards error - ${err.message}'))
 })

The question is: I want to redirect (res.redirect('/')) only when all boards were retrieved and saved. How can I do that? Where should I place xres.redirect('/') expression?


Solution

  • I think you need something like:

        var Promise = require('bluebird'); 
        var promises = [];
        trello.get("/1/members/me/boards") // resolves with array of board objects
     .each((board) => {
      // 
      promises.push( /*some promisified async call that return a promise, saving data in db or whatever asynchronous action. The important bit is that this operation must return a Promise.  */  );
     });
     //So now we have an array of promises. The async calls are getting done, but it will take time, so we work with the promises: 
    
     Promise.all(promises).catch(console.log).then( function(results){
          /*This will fire only when all the promises are fullfiled. results is an array with the result of every async call to trello. */
         res.redirect('/'); //now we are safe to redirect, all data is saved
     } );
    

    EDIT:

    Actually, you can avoid some boilerplate code using map instead of each:

    trello.get("/1/members/me/boards") // resolves with array of board objects
    .map((board) => {
        return somePromisifiedSaveToDbFunction(board);
    }).all(promises).catch(console.log).then( function(results){
     res.redirect('/'); 
    } );