Reza Karami Reza Karami - 3 months ago 8
Node.js Question

Returning one object that's built with nested promises

I'm struggling to wrap my head around a nested promise layout where one one object is returned at the end of it. My current code is as follows:

router

router.get(`/${config.version}/event/:id?`, function (req, res, next) {
var event = new Event(req, res, next);
event.getInfo(req.params.id).then((info) => {
res.send(info);
});
});


function

getInfo(id) {
db.main('events').where('id', id).select()
.then((result) => {
if(result.length > 0) {
var event = result[0];

//regular functions
event.status = this.getStatus(id);
event.content = this.getContent(id);
event.price = this.getPrice(id);

//promise functions
var users = this.getUsers(id);
var hosts = this.getHosts(id);

Promise.all([users, hosts]).then(values => {
event.users = values[0];
event.hosts = values[1];

//return whole event object to router
return event;
})
.catch((err) => {
return {
result: 'error',
error: err
};
});

} else {
return {
result: 'error',
error: "Event does not exist"
};
}
}).catch((e) => {
return {
result: 'error',
error: "Could not retrieve event info"
};
});
}


As you can see, the router initiates a call to get info about an event. The function then does a database call and gets some event data. Thereafter I need to get the users and hosts of the event from a different table, append that info to the event object as well and then return the whole object to the router to be sent to the client.

When I do this I get an error because I'm not returning a promise from the getInfo function, but I'm not sure how or which promise I'm supposed to return.

I'd appreciate some help with this. Thanks

Answer

using .then means that you are returning a promise.

function getInfo(id) {
  return new Promise(function(resolve, reject) {
    resolve('yay!');
  })
}
getInfo().then(function(result) { //result = yay! });

to make your code work, simply replace all the returns with resolves, the errors with rejects, and wrap the whole thing with a return new Promise as i did.

getInfo(id) {
  return new Promise(function(resolve, reject) {
    db.main('events').where('id', id).select()
      .then((result) => {
        if (result.length > 0) {
          var event = result[0];

          //regular functions
          event.status = this.getStatus(id);
          event.content = this.getContent(id);
          event.price = this.getPrice(id);

          //promise functions
          var users = this.getUsers(id);
          var hosts = this.getHosts(id);

          Promise.all([users, hosts]).then(values => {
              event.users = values[0];
              event.hosts = values[1];

              //return whole event object to router
              resolve(event);
            })
            .catch((err) => {
              reject({
                result: 'error',
                error: err
              });
            });

        } else {
          reject({
            result: 'error',
            error: "Event does not exist"
          });
        }
      }).catch((e) => {
        reject({
          result: 'error',
          error: "Could not retrieve event info"
        });
      });
  });
}

Comments