简体   繁体   中英

How to call a specific promise only once in Angular 1.5 when onInit hook is called multiple times

There is a API call that I am making on the onInit function.

   vm.$onInit = function() {
        var callInProgress = false;
        var resultsLoaded = false;

        var url = '/api/times/cst';
        if(callInProgress === false && resultsLoaded ===false){
            callInProgress = true;
            HttpWrapper.send(url,{"operation":'GET'}).then(function(result){
                vm.times = result;
                resultsLoaded = true;
                },function(error){
                vm.errorInApi = true;
            });
        }

Now $onInit is being called multiple times hence the two flags callInProgress, resultsLoaded are being initialized every time.

So, the check is kind of not working.

The API is being called each time the $onInit is called, multiple times on initialization.

How can I make the call only once? It has be called on $onInit though.

I advice wrapping the API call in a service like:

(function (angular) {
    'use strict';

    angular
        .module('services.common')
        .service('TimesService', TimesService);

    TimesService.$inject = ['HttpWrapper'];

    function TimesService(HttpWrapper) {
        var timesService = this;
        var timesResult = null;

        timesService.getTimes = getTimes;

        function getTimes() {
            if (!timesResult) {
                timesResult = HttpWrapper.send('/api/times/cst', {"operation": 'GET'});
            }
            return timesResult;
        }

        return timesService;
    }

})(angular);

and then inject it into your controller and use like TimesService.getTimes().then(...) , so the call to the API will be done only once on the first call of TimesService.getTimes (since the result would be stored in timesResult inside of the service).

callInProgress and resultsLoaded are within the onInit function and part of the directive controller. They are going to get created each time you use the directive. Using a controller property on the containing controller to do something similar would be the way to go. You can use bindings to specify the controller property you need to keep this somewhat generic.

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