0

Have some trouble with Angular promise between two loops... First loop walk through an array of value, and for each value, make a PouchDB Query to retrieve some datas. Finally, would like to return to controller a JSON Object that would look like :

{
    items: [
        {
            "attribute": "some value"
        },
        {
            "attribute": "some other value"
        },
        ...
    ],
    "a_total": "some_total",
    "another_total": "some_other_total"
 }

In this object, "items" Basically, put the code in a function that looks like :

    var _stockByAreas = function(){
        var deferred = $q.defer();

        var data = {}; // Final datas to return to controller


        // Get first array to loop into
        var storageAreas = storageAreaService.storageAreaList();

        var areas = []; // All of area

        // Walk across array
        angular.forEach(storageAreas, function(zone){
            var area = {}; // First object to return

            area.id = zone.id;
            area.libelle = zone.libelle;

            // Then make a PouchDB query to get all datas that involved
            MyKitchenDB.query(function(doc, emit){
                emit(doc.storage);
            }, { key: area.id, include_docs: true }).then(function (result) {

                area.sRef = "tabsController.addTo({id: '" + area.id + "'})";
                area.nbProduct = 0;
                area.totalQuantity = 0;
                area.totalValue = 0;

                // ... process result
                if(result.rows.length > 0){
                    // Some results, so... let's go
                    area.sRef = "tabsController.outFrom({id: '" + area.id + "'})";

                    var rows = result.rows;

                    // Counter initialization
                    var total = 0;
                    var value = 0;

                    angular.forEach(rows, function(row){
                        total++;

                        var stocks = row.doc.stock;
                        angular.forEach(stocks, function(stock){
                            var nearOutOfDate = 0;
                            var nearStockLimit = 0;
                            quantity += stock.quantity;

                            value += stock.quantity * stock.price;

                            // Evalue la date de péremption
                            var peremptionDate = moment(stock.until);
                            var currentDate = moment();
                            if(currentDate.diff(peremptionDate, 'days') <= 1){
                                nearOutDate += 1;
                            }

                        });
                        area.nbProduct = total;
                        area.qteTotale = quantity;
                        area.valeur = value;

                        if(quantite == 1){
                            nearLimitOfStock += 1;
                        }
                        areas.push(area); // Add result to main array
                    });   
                }
            }).catch(function (err) {
                // Traite les erreurs éventuelles sur la requête
            });

            /**
            * Hey Buddy... what i have to do here ?
            **/
            data.items = areas;
            data.nearLimitOfStock = nearLimitOfStock;
            data.nearOutOfDate = nearOutOfDate;
        });

        deferred.resolve(data);

        return deferred.promise;
    }

... But, console returns that "areas" is not defined, and other value too...

I think i don't really understand how promises runs...

Someone is abble to explain why i can't get the result that i expect in my case ? Thx

Jean-Luc Aubert
  • 620
  • 5
  • 19

1 Answers1

2

Your code is too long, I just give you the approach.
Use $q.all() to ensure all your queries are completed. And use deferred.resolve(data) whenever your data for each query is arrived.

var _stockByAreas = function() {

    var query = function(zone) {
        var queryDef = $q.defer();

        // timeout is for query and response simulations

        setTimeout(function() {
            // ...
            queryDef.resolve( {data: 'MeTe-30'} );
        }, 1000);
        return queryDef.promise;
    }

    var promises = [];

    angular.forEach(storageAreas, function(zone) {
        // ...
        promises.push( query(zone) );
    });

    return $q.all(promises);
}

_stockByAreas().then(function(res) {
    // res[0] resolved data by query function for  storageAreas[0]
    // res[1] resolved data by query function for  storageAreas[1]
    // ...
});
MeTe-30
  • 2,512
  • 2
  • 21
  • 30
  • Thx, i'll try $q.all()... I'd already cut my code in order to make another function to query my database but had the same problem, i think $q.all will resolve lot of hours... of pain. – Jean-Luc Aubert Jan 29 '17 at 17:44