1

Is there a way to pass a return value of one promise down the chain not to the next one but to the following ones? Currently we typically nest promises to keep the value in the function scope, like this:


return getOrder()
    .then(function (order) {
        return getOrderlines(order)
            .then(function (orderLines) {               
                //do something with order and orderlines
                processOrderAndOrderlines(order, orderLines);
            });
    })
    .then(function () { //do something else
    });

Is it possible to somehow pass the order object down the promise chain to get something similar to:

return getOrder()
    .then(function (order) {
        return getOrderlines(order);            
    })
    .then(function (orderLines) {               
        //do something with order and orderlines
        processOrderAndOrderlines(order, orderLines);
    });
    .then(function () { //do something else
    });
Michał Drozdowicz
  • 1,232
  • 11
  • 30
  • just return `order` (or `orderLines`) in `getOrderLines()` (instead of promise, which you're now doing?) and it's passed to following `.then()` as an argument. – Samuli Hakoniemi Feb 05 '15 at 11:21
  • @zvona that mean that I would need to anticipate what other callers might need from that function - I wouldn't normally return order from a function called getOrderLines. – Michał Drozdowicz Feb 05 '15 at 11:24
  • It might help you!! http://blog.credera.com/technology-insights/java/exploration-angularjs-promises-promises/ and http://stackoverflow.com/questions/25512015/how-to-flatten-this-promise-chain-angularjs-q – Anil Singh Feb 05 '15 at 11:26
  • @AnilSingh Unfortunately these answers don't tackle the problem of keeping access to the result of promises before the previous one (order in my example). – Michał Drozdowicz Feb 05 '15 at 13:16

2 Answers2

0

You can define a variable at the outer scope and set it inside of the promise:

var order, orderLines;

return getOrder()
    .then(function (result) {
        order = result;
        return getOrderlines(order);            
    })
    .then(function (result) {               
        //do something with order and orderlines
        orderLines = result;
        processOrderAndOrderlines(order, orderLines);
    });
    .then(function (result) { //do something else

    });
jdachtera
  • 749
  • 1
  • 6
  • 11
  • This would work of course. I wonder if there's a solution without the additional variables, though. Let me wait for a different answer for a while before I accept this one. – Michał Drozdowicz Feb 05 '15 at 13:19
0

If you need to use both orderLines and initial order object in processOrderAndOrderlines, then cleanest way is to resolve getOrderlines promise with some sort of map which would include order object too. For example like this:

function getOrderLines(order) {
    // Some promise flow, e.g.:
    return $http.post('getOrderLines', {order: order}).then(function(response) {
        return {
            order: order,
            orderLines: response.data
        }
    });
}

then you would be able to use it this way:

return getOrder()
   .then(function (order) {
       return getOrderlines(order);
   })
   .then(function (data) {
       return processOrderAndOrderlines(data.order, data.orderLines);
   })
   .then(function (result) {
      console.log(result)
   });
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • The issue here is that in one usage of getOrderLines I might be interested in getting order as part of "data", but in other cases it might something else. This limits the reusability of this function. I guess I could make all functions accept an additional array of parameters that are simply added to the result array, but that seems like overkill. – Michał Drozdowicz Feb 05 '15 at 13:18