1

New to q, I got a sample code as follow, what it does is, get an order, then get the owner of the order, append the name of the owner to the order so that the complete order can be displayed, how to change this to using Q (kriskowal/q)? Thanks,

db.get_order(order_id, function(err, order) {
users.get_user(order.user_id, function(err, user) {
    order['$user_name'] = user.name
    console.log(order)
  })
})
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
AngeloC
  • 3,213
  • 10
  • 31
  • 51

1 Answers1

1

I am assuming that get_order function depends on the db object and also get_user depends on user object. If that is the case, then you need to invoke those methods with Q.ninvoke, like this

Q.ninvoke(db, "get_order", order_id)
.then(function(order) {
    return Q.ninvoke(user, "get_user", order.user_id);
})
.then(function(user) {
    console.log(user.name);
})
.catch(function(err) {
    console.error(err);
});
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • Thanks for the quick answer, the purpose is not to get the user.name, but to add the user.name to the order, and when reach .then(function(user) { order['$user_name'] = user.name}, problem is, how to access the object order at this point? – AngeloC Apr 16 '14 at 14:16
  • @AngeloC You can retain the retrieved order by storing it in a variable outside the `Q` functions, will that work for you? – thefourtheye Apr 16 '14 at 14:19
  • a variable outside of Q functions works, thanks. – AngeloC Apr 16 '14 at 14:47
  • It is also possible to `return [order,Q.ninvoke(user,...)]` and then do `.spread(function(order,user){` instead of the `.then` on user and access it there. You can also always nest but no one likes nesting. On a side note, you should use `nfbind` when possible instead of invoking nfcall each time. – Benjamin Gruenbaum Apr 16 '14 at 14:48
  • @BenjaminGruenbaum You are correct, if the OP uses it more than once he can `bind` it – thefourtheye Apr 16 '14 at 14:49
  • @AngeloC If you are calling `db.get_order`/`user.get_user` often, you need to use `Q.nfbind`. Check that in the API Docs, if you need clarifications, please feel free to comment here :) – thefourtheye Apr 16 '14 at 14:51
  • @BenjaminGruenbaum nbind works too, following is a rewrite, is it correct? var get_order = Q.nbind(dao.get_order, dao) var get_user = Q.nbind(users.get_user, users) var order get_order(order_id) .then(function(order_) { order = order_ return get_user(order.user_id) }).done(function(user) { order.$user_name = user.name console.log(order) }) – AngeloC Apr 16 '14 at 15:20
  • @AngeloC In all honesty? I'd use Bluebird, it's a much faster library, it promisifies a lot better with `promisifyAll`, it detects unhandled rejections and it manages contexts with `.bind`. – Benjamin Gruenbaum Apr 16 '14 at 15:24
  • @BenjaminGruenbaum will take a look at Bluebird, reason I choose q is, it is the one use in angularjs, and that's the front end I'm using now, in fact it is angularjs convince me to use Promise:) – AngeloC Apr 16 '14 at 15:28
  • @AngeloC AngularJS does not use Q it uses `$q` which is a really dumbed down version of Q with slightly different semantics. Both Q and Bluebird implement the Promises/A+ specification and all of `$q`s methods. I'm glad you like promises, they really do help. – Benjamin Gruenbaum Apr 16 '14 at 15:30