Search code examples
angularjsmongoosemean-stackq

deferred.resolve() is not iterating the last element inside a forloop


in the model.findone i'm getting a array which consists of 3 elements. In the else part i'm looping through each item & fetching offering head of that particular item.

But i'm able to get only 2 offering heads.Not able to fetch the last offering head. Is there any problem with my code??

function getOfferingsHeads(id) {
    var deferred = Q.defer();
    var offeringHeads = [];
    model
    .findOne({ _id: id })
    .exec(function (err, item) {
        if(err) {
            console.log(err);
            deferred.reject(err);
        }
        else {
            // deferred.resolve(item.offerings);
            // var offeringsList = [];
            // offeringsList = item.offerings;

            for (var i = 0; i < item.offerings.length; i++) {
                executivesModel
                .findOne({offName: item.offerings[i] })
                .exec(function(err1, item1) {
                    if(err1){
                        console.log(err1);
                        deferred.reject(err1);
                    }
                    else{
                        offeringHeads.push(item1.offHead);
                        deferred.resolve(offeringHeads);
                    }
                });
            }
        }
    });
    return deferred.promise;
}

Solution

  • You can't resolve a deferred more than once, and in general you shouldn't be using deferreds at all. Since mongoose has a promise-friendly API, you should just use that. It will make your code much much cleaner:

    function getOfferingHead(offName) {
        return executivesModel
            .findOne({offName: offName })
            .exec()
            .then(function (item) {
                return item.offHead;
            });
    }
    
    function getOfferingsHeads(id) {
        return model
            .findOne({ _id: id })
            .exec()
            .then(function (item) {
                return Q.all(item.offerings.map(getOfferingHead));
            });
    }
    

    To use the function:

    getOfferingsHeads('myId').then(function (heads) {
        console.log(heads);
    });