0

I am trying to get the savePlaces array as the final output so that I can return it in the response. But I am getting success as undefined in function2(). Why I am not getting the savePlaces as expected. Please provide solution....

var saveOverriddenPlaces = function(index, savePlaces) {
    var groupSettingsDAO = new GroupSettingsDAO();
    var deferred = q.defer();
    if (index == savePlaces.length) {
        console.log("-----------------------------deferred--------------------------------", deferred);
        console.log("LAST RETURN -----------------------------" + savePlaces + "----------------------------------------------------", index);
        deferred.resolve(savePlaces);
        return deferred.promise;
    }
    var placeInfo = {
        "id": savePlaces[index].id,
        "groupurl": savePlaces[index].groupurl,
        "sla": savePlaces[index].sla
    };
    if (savePlaces[index]._id) {
        placeInfo._id = savePlaces[index]._id;
        //update the overriden places in the database
        groupSettingsDAO.updateOverriddenPlace(placeInfo)
            //updates the overriden place and sends result in response when successful else logs error
            .then(
                //success
                function(success) {
                    console.log("recursion ============" + index + "=======================");
                    deferred.resolve(saveOverriddenPlaces(++index, savePlaces));

                    return deferred.promise;
                },
                //failure
                function(error) {
                    console.log("PLACES     ERROR ===================================", error);
                });
        // placesWithID.push(value);
    }
    //WITHOUT ids
    else {
        placeInfo._id = guid();
        savePlaces[index]._id = placeInfo._id;
        groupSettingsDAO.saveOverriddenPlace(placeInfo)
            // saves the overridden place and sends the results in response if successful else logs the error
            .then(
                //success
                function(success) {
                    console.log("recursion ============" + index + "=======================");
                    deferred.resolve(saveOverriddenPlaces(++index, savePlaces));
                },
                //failure
                function(error) {
                    console.log("PLACES     ERROR ===================================", error);

                });
    }
}
function2(req, res) {
    saveOverriddenPlaces(0, req.savePlaces).then(function(success) {
        //getting success as undefined 
        res.send({
            "result": success
        });
    });
}
1
  • I am using the Q library and groupSettingsDAO is a dao object which has method updateOverriddenPlace() which returns a promise. Commented May 22, 2015 at 22:35

2 Answers 2

1

This is because saveOverriddenPlaces is not returning a value and therefore it is not passed to the .then statement in function two. The "solution" is to make sure that saveOverridenPlaces returns a Promise that calls resolve with a value that you want to pass to success.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for replying but I too understood that the saveOverriddenPlaces is not returning the promise. The problem is I am not able to figure out how I can do that. As I tried returning the array with updated values on the last index value. I read other articles on recursion with node.js using promises but was not able to solve this problem.
Understood the problem.
0

The problem is that in the line

deferred.resolve(saveOverriddenPlaces(++index, savePlaces));

your saveOverriddenPlaces function does not (always) return a promise or a value. If a function is asynchronous, it must always return a promise.

You can easily do that by adding a return before the groupSettingsDAO.…().then(…) calls in your conditional statements - as then does return exactly the promise that you want if you return a value/prmise from its callback.

However, you should try to avoid the deferred antipattern. For your base case, use the Q function to create a fulfilled promise, for everything else just chain then calls - no deferreds needed.

function saveOverriddenPlaces(index, savePlaces) {
    if (index == savePlaces.length) {
        console.log("LAST RETURN -" + savePlaces + "-", index);
        return Q(savePlaces);
    }
    var groupSettingsDAO = new GroupSettingsDAO();
    var placeInfo = {
        "id": savePlaces[index].id,
        "groupurl": savePlaces[index].groupurl,
        "sla": savePlaces[index].sla
    };
    var promise;
    if (savePlaces[index]._id) {
        placeInfo._id = savePlaces[index]._id;
        promise = groupSettingsDAO.updateOverriddenPlace(placeInfo); //update the overriden places in the database
        // placesWithID.push(value);
    } else { // WITHOUT ids
        placeInfo._id = guid();
        savePlaces[index]._id = placeInfo._id;
        promise = groupSettingsDAO.saveOverriddenPlace(placeInfo) // saves the overridden place
    }
    return promise.then(function(success) {
//  ^^^^^^
        console.log("recursion =" + index + "=" + success);
        return saveOverriddenPlaces(++index, savePlaces));
//      ^^^^^^
    });
}
function2(req, res) {
    saveOverriddenPlaces(0, req.savePlaces).then(function(success) {
        //getting success as undefined 
        res.send({
            "result": success
        });
    }, function(error) {
        console.log("PLACES ERROR =", error);
    });
}

1 Comment

Thank you for replying Bergi. I finally understood where I made my mistake.:-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.