0

I have a partial in which data is coming from multiple controllers, not the situation is those functions which are called in the controller,they are hitting the server for more than fifty times, and they keep hitting as long as they dont get the response from server. I dont know how to tackle this situation please guide me.

mainControllers.controller('AddProductController', ['$scope', '$http', '$routeParams', '$cookies', '$rootScope', 'Upload', '$timeout', '$uibModal', '$log', '$document', '$window', 'variantsService', 'toaster', '$route', '$rootScope', 'Lightbox', function ($scope, $http, $routeParams, $cookies, $rootScope, Upload, $timeout, $uibModal, $log, $document, $window, variantsService, toaster, $route, $rootScope, Lightbox) {


    /*Currency dynamic*/
    $scope.currency = function () {
        $http.get('currencies',
                {headers:
                            {'Content-Type': 'application/x-www-form-urlencoded',
                                'Authorization': $rootScope.keyword_auth_token, 'Accept-Language': $cookies.get('type')}
                })
                .success(function (data) {
                    $scope.user_curr = data[0].code;
                })
                .error(function (data) {
                    console.log(data);
                });
    };

    /*Currency dynamic ends here*/
    $scope.currency();

}]);

Is there any way, any way, so that I can limit this thing?

Usman Iqbal
  • 2,379
  • 5
  • 26
  • 50
  • the above got will only execute once.. May be you have missed the logic which makes multiple calls to the function. – Atul Sharma Feb 08 '17 at 12:10
  • 1
    How is it getting called recursively? The given code does not help debugging the issue; may be the issue is in some other place – Developer Feb 08 '17 at 12:10
  • Is the request not getting any response at all? If so the browser trys to resend the request because it thinks its lost. We had this issue when 1 of our webservices wasnt returning anything – stackg91 Feb 08 '17 at 12:11
  • Is this controller used numerous times in view? Not enough detail provided – charlietfl Feb 08 '17 at 12:12
  • This code will be executed only once. There is however a possibility that this controller block is being formed multiple times. Please share the View / Partial. – Tariq B. Feb 08 '17 at 12:12
  • See this http://stackoverflow.com/questions/14302512/what-happens-when-no-response-is-received-for-a-request-im-seeing-retries – stackg91 Feb 08 '17 at 12:14

3 Answers3

0

I always put the calls in a service, and then you can take full control. Something like this:

app.service("currencyService", function($q, $http) {
    var _currencyPromise = null,
        _currencies = null;

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

        // Check if the currencies are resolved before
        // If so, immediately return these
        if (_currencies) {
            deferred.resolve(_currencies);
        } 
        // Else check if the promise is already running
        // If so, use that promise
        else if (_currencyPromise) {
            _currencyPromise.then(function(response) {
                deferred.resolve(response.data);
            });
        }
        // Else make the http call and assign to the promise
        // So that the promise can be used instead of a new http call
        else {
            _currencyPromise = $http.get("..");
            _currencyPromise.then(function(response) {
                // Assign data to the currencies, so that it can be used
                // by next calls immediately
                _currencies = response.data;
                deferred.resolve(_currencies);
            }, function(error) {
                // something went wrong
                _currencyPromise = null;
                deferred.reject();
            });
        }

        return deferred.promise;
    }
});

Then in your controllers you can always use this service, while the http call will only be made once:

app.controller("myCtrl", ["$scope", "currencyService", function($scope, currencyService) {
    currencyService.getCurrencies().then(function(currencies) {
        $scope.user_curr = currencies[0].code;
    });
}]);

See this jsfiddle for reference. In the console you can see that the API is only called once.

devqon
  • 13,818
  • 2
  • 30
  • 45
  • 1
    no need for the extra `$q.defer();` if you just store `_currencyPromise` and return that promise. `if(!_currencyPromise){ _currencyPromise = $http.get(...)} return _currencyPromise` – charlietfl Feb 08 '17 at 12:21
  • That is true, but I like to use this pattern to be able to immediately resolve an existing object (in this case the `currencies`) because sometimes I do additionally stuff like loading it from `localStorage` – devqon Feb 08 '17 at 12:24
  • Sure..understand...in this case not applicable though – charlietfl Feb 08 '17 at 12:25
  • Just out of curiosity: why wouldn't use use the default $http cache mechanism in this particular case? – skubski Feb 08 '17 at 12:55
  • @skubski because AFAIK angular only caches the response, so it will still fire every request until the request is resolved when you use the cache. Please correct me if I'm wrong :) – devqon Feb 08 '17 at 12:58
0

It definitely is a bad idea to have multiple controllers for a single partial. You should consider using angular factories for maintaining data in such cases. But to provide you a short solution, you should remove the line $scope.currency(); from your controller (because it would make an api call as soon as your controller is initialized) and consider using ng-init built-in directive. So, basically in your partial where you are using ng-controller="AddProductController", you can add ng-init="currency()" (If you want to make an api call).

Anadi Sharma
  • 295
  • 1
  • 8
0

I came up with a quite simple solution. For example I have a view like this

<div ng-controller="HomeController">                    
<div class="active tab-pane" ng-controller="AddProductController" ng-init="subcategories_id();currency();">

<p>{{user_curr}}</p>

</div><!--ends here->
<p>first controller {{abc}}</p>
</div>

I am using the nginitwhich works fine.

Usman Iqbal
  • 2,379
  • 5
  • 26
  • 50