-1

Following are the functions in node.js using promise.

exports.getDetailsByUserId = function(req,res) {
     getUserDetails(req, res) // function to get user details
    .then(function (Details) {
        var allpromises = Details.map(getStatus); //get and update the status of user
        return allpromises
    })
    .then(function (promises) {
        var orderresult =[];
        Q.allSettled(promises)
        .then(function (allpromises) {
            orderresult.push(allpromises);
        })
        return orderresult;
    })
    .then(function (result) {
        getUserDetails(req, res)//again calling get user details so that i will get modified result
       .then(function (data) {
            res.json({                             
                "User" : data
            })
        })
    })
    .catch(function (error) {
        console.log(error);
        res.status(200).json({
            "Message": error
        })
    })
}

var getStatus = function (data,req) {
    var deferred = Q.defer();
        requestify.post('http://example.com', {
            "data": [{ "Number": No }]
        })
    .then(function (response) {
            response.getBody();
            response.body;
            var Status = JSON.parse(response.body);
          var Details = { "_id": data._id, "Status": Status.status[0] };
          return OrderDetails;
    })
    .then(function (DetailsData){
        var req = { body : { Details :DetailsData} };
       updateDetails(req).then(function (data) { 
          deferred.resolve;
        })
    })
   .catch(function (error) {                     
        deferred.resolve(error);
   });    
    return deferred.promise;
}

The getUserDetails function gets details of user first time, then getStatus calls another API and updates related user status. To this point every thing is working fine.

I need to call getUserDetails a second time to get updated results, but it does not give update results. Maybe it gets called before updating the status? What might be wrong with the code so that it will execute after Q.all?

Thank you.

Daniel Beck
  • 20,653
  • 5
  • 38
  • 53
sam
  • 3
  • 2
  • 4
  • What's the point of `orderresult`? To wrap an array in an array? – Bergi Sep 26 '16 at 12:02
  • You should not need to call `getUserDetails` twice. Just having them updated, wouldn't you know what they are already? – Bergi Sep 26 '16 at 12:04
  • orderresult is an array of promise. I want to get the updated result to display in gird – sam Sep 26 '16 at 12:24
  • 1
    No it's not. And that's likely your problem. – Bergi Sep 26 '16 at 12:27
  • But i have used same thing in one of my function and its working as required.What is the solution for this ? – sam Sep 26 '16 at 12:28
  • 1
    You're not waiting for `Q.allSettled(promises)` to finish, before the second time you call `getUserDetails(req, res)`. Another async javascript question... – cviejo Sep 26 '16 at 12:44
  • How to handle the same since as per my knowledge "then" will execute one after other.Correct me if wrong. – sam Sep 26 '16 at 13:18
  • Someone took the time to write a very good and extensive answer to that question, please mark it as correct answer. – cviejo Sep 26 '16 at 16:37

1 Answers1

0
var orderresult =[];
Q.allSettled(promises)
.then(function (allpromises) {
    orderresult.push(allpromises);
})
return orderresult;

You fell for the classical mutation in asynchronous callback problem. The then callback is asynchronous, and the orderresult will not contain the allpromises array when it's returned. To make something wait for the promise, you have to return it.

In any case, you should simplify your code to

getUserDetails(req, res)
.then(function (details) {
    var allpromises = details.map(getStatus);
    return Q.allSettled(allpromises); // just call it here already and return a promise
})
.then(function (allpromiseresults) {
    var orderresult = [allpromiseresults]; // not sure what this is good for
    return orderresult;
})
.then(function (result) { // given that you don't use the `result` anyway
    return getUserDetails(req, res);
}).then(function (data) {
    res.json({                             
        "User" : data
    })
}, function (error) {
    console.log(error);
    res.status(200).json({
        "Message": error
    })
});

and in getStatus you should avoid the deferred antipattern:

function getStatus(data,req) {
    return requestify.post('http://example.com', {
        "data": [{ "Number": No }]
    })
    .then(function (response) {
        response.getBody(); // ???
        var status = JSON.parse(response.body);
        var details = { "_id": data._id, "Status": Status.status[0] };
        // no `OrderDetails`, no `DetailsData`

        var req = {body: {Details: details}};
        return updateDetails(req) // probably "getStatus" should be called "updateStatus"
    });
}
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thank u for valuable time and extensive answer, but this still executes second call to "getUserDetails" before Q.allSettled(allpromises) returns and gives unmodified result. Now am trying to call updateDetails after all Q.allSettled(allpromises) hope it will work instead of calling in getStatus. – sam Sep 27 '16 at 07:00
  • @sam If it does that, you probably have forgotten a `return` somewhere. My code certainly doesn't call the second `getUserDetails` after `allSettled` *returns*, and it even waits until the promise *fulfills*. What gives you the impression that it happens "before"? Maybe there's a bug within `updateDetails` (which you haven't shown). Make sure the promise it returns does work. – Bergi Sep 27 '16 at 10:41
  • have modified above code to handle in then.its working now. – sam Sep 27 '16 at 12:40
  • @sam You should not edit my answer (except for obvious mistakes or improvements) but post a comment instead. Given that [your suggestion](http://stackoverflow.com/review/suggested-edits/13808591) does involve a `deferred`, you don't seem to use my answer - you don't need any deferreds at all! Please read the link on the antipattern. – Bergi Sep 27 '16 at 14:51