Search code examples
javascriptangularjsangular-promisees6-promise

Promise.all() return an unexpected value


I'm really confused with my bit of code, which is an angularjs service. I tried to use Promise.all to concatenate the two promises that are part of the service, and to send the result to my controller. The thing is that the object returned by Promise.all is composed by the two same arrays. My code here, just to be clearer:

batchModule.service('BatchService', ['$http', '$q', '$log', 'MessageboxService', function ($http, $q, $log, MessageboxService) {

let deferred = $q.defer();

this.loadAll = () => {

    promise1 = () => {
        $http.get(_restApiPath + "/batch/?processtype=IMPORT_CUSTOMER")
        // loadLastFiveBatch('IMPORT_CUSTOMER')
            .then(function (response) {
                deferred.resolve(response.data);
                // datas.push(response1);
                // console.log(datas);
            }, function (error) {
                deferred.reject(error);
                $log.error(error);
            });
        return deferred.promise;
    };

    promise2 = () => {
        $http.get(_restApiPath + "/batch/?processtype=IMPORT_LAB_MARGIN")
        // loadLastFiveBatch('IMPORT_LAB_MARGIN')
            .then(function (response) {
                deferred.resolve(response.data);
                // datas.push(response2);
                // console.log(datas);
            }, function (error) {
                deferred.reject(error);
                $log.error(error);
            });
        return deferred.promise;
    };

    Promise.all([promise1(), promise2()])
    .then(values => {
        console.log(values);
    });

};
}]);

The console.log(values) return an object made of 2 equal arrays returned by the IMPORT_CUSTOMER request, when the second argument of the Promise.all is precisely a promise returned by the IMPORT_MARGIN request. I'have been working on it few hours today but I can't find any solution. I hope I was clear enough, my english is not great. Thank you for your answers :-)


Solution

  • Problem caused because you used single deferred for all of your promise. So that single that reference get resolved, it will resolved for further instances of your promise call. So rather use different deferred for each request. Still I don't preferred to use deferred anti-pattern. Rather use build in promise return by $http.get method.

    Additionally you had Promise.all at the end of the function, this won't run angular digest cycle. Eventually if you are going to update any bindings from this function won't update bindings on UI. Consider chainging it to use $q.all

    this.loadAll = () => {
    
        promise1 = () => {
            return $http.get(_restApiPath + "/batch/?processtype=IMPORT_CUSTOMER")
                .then(function (response) {
                    return response.data;
                }, function (error) {
                    $log.error(error);
                    return $q.reject(error);
                }
            );
        };
    
        promise2 = () => {
            $http.get(_restApiPath + "/batch/?processtype=IMPORT_LAB_MARGIN")
            // loadLastFiveBatch('IMPORT_LAB_MARGIN')
                .then(function (response) {
                    return response.data;
                }, function (error) {
                    $log.error(error);
                    return $q.reject(error);
                }
            );
        };
        //return is needed if any function is trying to chain `loadAll` function.
        return $q.all([promise1(), promise2()])
        .then(values => {
            console.log("promise1", values[0]);
            console.log("promise2", values[1]);
        });
    
    };