How to avoid repeating HTTP requests angularjs

Is there a way in Angular to avoid repeating HTTP requests? As you can see in the above code, I am calling to get product details. The thing is, this call is associated with a button ... I would avoid repeated calls. If I clicked on the detailed product button, I obviously don't need to call my service again .... the correct way is to download the information once and then show and hide; but I don't know how to do it in Angular. (also i dont want to download detailed product from scraper for very product, i only want to download on demand of clic user but once)

$scope.seeInfo= function(id){

    $http.get('/shop/getDetailInfo/'+id).
        success(function(data, status) {
            $scope.info = data.detailinfo;
            if (data.detailinfo>0) $scope.showDetails=true;
            else $scope.showDetails=false;
        });

};

      

+3


source to share


3 answers


You can store each element of the user request in a factory and then check if the content is in the factory before the ajax call.

   $scope.seeInfo= function(id){
        var detailinfo = someFactory.get(id); //get item data from factory if exist
        if (angular.isUndefined(detailinfo) || detailinfo === null) {
            $http.get('/shop/getDetailInfo/'+id).
                success(function(data, status) {
                    someFactory.set(id, data); //set ajax data to factory
                    $scope.info = data.detailinfo;
                    if (data.detailinfo>0) $scope.showDetails=true;
                    else $scope.showDetails=false;
                });
            }
        } else {
            $scope.info = detailinfo;
            if (detailinfo>0) $scope.showDetails=true;
            else $scope.showDetails=false;
        }
    };

      

As someone said you can use the $ http cache, but I don't know how it works.

UPDATE

SomeFactory example:

.factory('someFactory', [function() {

    var storedItems = [];

    return {
        get: function(id) {
            return storedItems[id];
        },
        set: function(id, data) {
            storedItems[id] = data;
        }
    };

}]);

      



check the factory:

someFactory.set(12345, {"info":"Hello"});
someFactory.set(2, "World");

console.log(someFactory.get(12345).info); // returns Hello
console.log(someFactory.get(2)); //returns World

      

You can store strings, objects ...

Hope this helps you

UPDATE2 FULL CODE EXAMPLE

var someApp = angular.module("someApp", [])

.controller('someCtrl', ['someFactory', function(someFactory) {

  someFactory.set(12345, {"info":"Hello"});
  someFactory.set(2, "World");

  console.log(someFactory.get(12345).info); // returns Hello
  console.log(someFactory.get(2)); //returns World

}]).factory('someFactory', [function() {

    var storedItems = [];

    return {
        get: function(id) {
            return storedItems[id];
        },
        set: function(id, data) {
            storedItems[id] = data;
        }
    };

}]);

      

+2


source


Angular $ http has a built in cache function, maybe all you need

https://docs.angularjs.org/api/ng/service/$http

$scope.seeInfo= function(id){

    $http.get('/shop/getDetailInfo/'+id, {cache: true}).
        success(function(data, status) {
            $scope.info = data.detailinfo;
            if (data.detailinfo>0) $scope.showDetails=true;
            else $scope.showDetails=false;
        });

};

      

Update



I see that you have opted to use a "fold your" solution instead, which is generally more error prone than using angular.

Here's how to achieve the same:

// access the $http cache 
var httpCache = $cacheFactory('$http');
// retrieve an element from cache
var detailInfo = httpCache.get('/shop/getDetailInfo/' + id);
// delete a cache element
httpCache.remove('/shop/getDetailInfo/' + id);

      

+5


source


Bind first call with scope variable.

$scope.wasCalled = false;
$scope.seeInfo= function(id){
    if ( $scope.wasCalled == false ) {
    $http.get('/shop/getDetailInfo/'+id).
        success(function(data, status) {
            $scope.info = data.detailinfo;
            $scope.wasCalled = true;
        });
    }
};

      

it is set to success, so the server error code will be between 200 and 299. Then you can set ng-show given the variable $scope.wasCalled

.


Here is an implementation considering various calls to id.

$scope.callIds = [];
$scope.wasCalled = function(id){
for ( var k = 0 ; k < $scope.callIds.length ; k++ ) 
    if ( $scope.callIds[k] == id ) 
        return true;
return false;
};
$scope.addCalled = function(id){
    $scope.callIds.push(id);
};
$scope.seeInfo= function(id){
    if ( $scope.wasCalled(id) == false ) {
    $http.get('/shop/getDetailInfo/'+id).
        success(function(data, status) {
            $scope.info = data.detailinfo;
            $scope.addCalled(id);
        });
    }
};

      

Checking if the specified id was specified, if not, call with $ http and add id to the list.

+1


source







All Articles