简体   繁体   中英

AngularJS http promise firing 4 times

I am using AngularJS to call an http service that returns some opening times in an object. I don't understand why, in my controller, the console.log is printed 4 times, instead of one time. Can anyone explain this to me?

Here is my service/factory code:

myApp.factory('BookingFactory', ['$http', '$q', function($http, $q) {
    var deferredTime = $q.defer();

    return {
        GetDealerLocationTimeList: function(websiteId) {
            return $http.get('/d/GetDealerLocationTimes?website_id=' + websiteId)
                .then(function(response) {
                    deferredTime.resolve(response.data);
                    dealerLocationTimeList.push(response.data);
                    return deferredTime.promise;
                }, function(error) {
                    deferredTime.reject(response);
                    return deferredTime.promise;
                });
        }
    }
}]);

Here is my controller code that is calling the service:

var promise = BookingFactory.GetDealerLocationTimeList(website_id);

promise.then(
    function(da) {
        $scope.dealerLocationTimeList = da;
        console.log($scope.dealerLocationTimeList);
    },
    function(error) {
        $log.error('failure loading dealer associates', error);
    }
);

There are many mistakes in this code ><

If you want to use deferred, then this should be the code:

myApp.factory('BookingFactory', ['$http', '$q', function($http, $q) {
    return {
        GetDealerLocationTimeList: function(websiteId) {
            var deferredTime = $q.defer(); // deferred should be created each time when a function is called. It can only be consumed (resolved/rejected) once.

        /* return - don't need to return when you already creating a new deferred*/ 
            $http.get('/d/GetDealerLocationTimes?website_id=' + websiteId)
                .then(function(response) {
                    deferredTime.resolve(response.data);
                    // dealerLocationTimeList.push(response.data);
                }, function(error) {
                    deferredTime.reject(error); // it should be 'error' here because your function argument name says so...
                });

           return deferredTime.promise; // promise is returned as soon as after you call the function, not when the function returns
        }
    }
}]);

But it is a better practice to return the promise if your inner function is a promise itself (like $http.get )

myApp.factory('BookingFactory', ['$http', '$q', function($http, $q) {
    return {
        GetDealerLocationTimeList: function(websiteId) {
            // no need to create new deferred anymore because we are returning the promise in $http.get
            return $http.get('/d/GetDealerLocationTimes?website_id=' + websiteId)
                .then(function(response) {
                    // dealerLocationTimeList.push(response.data);
                    return response.data; // return the data for the resolve part will make it available when the outer promise resolve
                }/* this whole part should be omitted if we are not doing any processing to error before returning it (thanks @Bergi)
                , function(error) {
                    return $q.reject(error); // use $q.reject to make this available in the reject handler of outer promise
                }*/);

            // no need to return promise here anymore
        }
    }
}]);

You can see I've also commented your dealerLocationTimeList.push(response.data) . In this case you should push the data into your scope variable on the outer layer (in the promise.then), because dealerLocationTimeList is not available in the factory.

promise.then(
    function(da) {
        // you might want to do an isArray check here, or make sure it is an array all the time
        $scope.dealerLocationTimeList.push(da);
        console.log($scope.dealerLocationTimeList);
    },
    ...
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM