Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
How to avoid calling this method twice?
Message
Information générale
Forum:
Javascript
Catégorie:
Autre
Divers
Thread ID:
01611738
Message ID:
01611859
Vues:
44
That approach works - I use it all the time to cache data. if it doesn't you likely have a logic error somewhere in determining whether the data is already present or you're not storing the data properly in a persistent place where it survives.

Your service looks wrong in a number of ways - I don't know how you're accessing it but you wouldn't be able to even call your getMetaData function on the service since its private.

This is how I would set this up:
app.factory('invoicesService', ['$http', '$q', function($http, $q) {
 
       // Interface
       var service = { 
                metaData: null,      
                getMetaData: getMetaData
       }
       return service;

       // Implementation

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

            if (service.metaData)
                deferred.resolve(service.metaData);
            else {
                $http.get('/api/invoices/metadata')
                    .success(function (data) {
                        service.metaData = data;
                        deferred.resolve(data);

                    })
                    .error(function (data, status, header, config) {
                        deferred.reject(status);
                    });
            }
            return deferred.promise;
        };

}
You don't have to make the metaData public, but my guess is that's what you actually want so it stays accessible and updateable by external code.

+++ Rick ---

>Nice article. We use the first approach in our code.
>
>I tried what you suggested (e.g. my new code is
>
>
>app.factory('invoicesService', ['$http', '$q', function($http, $q) {
>
>        var metaData = null;
>
>        var getMetaData = function () {
>            var deferred = $q.defer();
>
>            if (angular.isObject(metaData))
>                deferred.resolve(metaData);
>            else {
>                $http.get('/api/invoices/metadata')
>                    .success(function (data) {
>                        metaData = data;
>                        deferred.resolve(data);
>
>                    })
>                    .error(function (data, status, header, config) {
>                        deferred.reject(status);
>                    });
>            }
>            return deferred.promise;
>        };
>
>but I still got hit of my API controller's method twice. I'm going to look into Viv's idea now.
>
>>You need to return a promise even if you return the cached data.
>>
>>So define your deferred at the top of the code then to return the cached data:
>>
>>
>>if (angular.isObject(metaData)) {
>>      deferred.resolve(metaData);
>>     return deferred.promise;
>>}
>>
>>
>>This way you get the same data back regardless of whether the data was returned from the AJAX call or from the cached data.
>>
>>You might want to read this:
>>http://weblog.west-wind.com/posts/2014/Oct/24/AngularJs-and-Promises-with-the-http-Service
>>
>>which explains some of the mechanics behind this...
>>
>>+++ Rick ---
>>>
>>
>>
>>Define your $q.defer() before the first call then deferred.resolve(metaData); return deferred.promise() with the cached data and return the promise in the if block.
>>
>>+++ Rick ---
>>
>>>Hi everybody,
>>>
>>>I have two pages in the same form that need to access the same data.
>>>
>>>Each of the pages is controlled by its own controller and both have this code in the init:
>>>
>>>
>>>invoicesService.getMetaData().then(function (data) {
>>>                        $scope.invoicesMetaData = data;
>>>
>>>                    });
>>>
>>>So, I want to somehow adjust the service code to not invoke the method twice. Here is what I attempted to do but it's not working:
>>>
>>>
>>>app.factory('invoicesService', ['$http', '$q', function($http, $q) {
>>>
>>>        var metaData = null;
>>>
>>>        var getMetaData = function () {
>>>            if (angular.isObject(metaData))
>>>                return metaData;
>>>
>>>            var deferred = $q.defer();
>>>            $http.get('/api/invoices/metadata')
>>>                .success(function (data) {
>>>                    metaData = data;
>>>                    deferred.resolve(data);
>>>                    
>>>                })
>>>                .error(function (data, status, header, config) {
>>>                    deferred.reject(status);
>>>                });
>>>            return deferred.promise;
>>>        };
>>>
>>>I still get 2 hits in my API controller. Do you see how should I change the above to avoid the second call after the first one was already made?
>>>
>>>Thanks in advance.
+++ Rick ---

West Wind Technologies
Maui, Hawaii

west-wind.com/
West Wind Message Board
Rick's Web Log
Markdown Monster
---
Making waves on the Web

Where do you want to surf today?
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform