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:
01611865
Vues:
49
When I tried this code exactly, I got functions undefined. So I moved implementation on the top and the var service at the bottom and it worked. I also had to declare var metaData at the very top in the code before function declarations.

In any case, after I made that change (e.g. used one service variable instead of return of anonymous object with all function definitions) I still got the same behavior as before.

>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.
If it's not broken, fix it until it is.


My Blog
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform