3

Is there a way in Angular to avoid repeating http requests? As you can see in the code above I'm making a call to retrieve the detailed info of a product. The fact is that this call is associated to a button... I would to avoid repetitive calls. If I have clicked on the detailed-product-button obviously I don't need to make a call again to my service....the proper way will be to load the info once and then show and hided; but I don't know how to manage this on Angular. (also I don't want to load the detail product from the scrach for very product, I want to loaded only on user's clic demand, 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 Answers 3

5

Angular $http has a cache functionality built in, might be 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 you went for the "roll your own" solution instead, which generally is more bug prone than using what angular provides.

Here 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);
Sign up to request clarification or add additional context in comments.

2 Comments

Fantastic! this works perfectly, thanks a lot. Now I'm wondering if my approach is correct, because I think is not very smarty to make a call every time you show hide elements..
I recommend you read John's Papa best practice (github.com/johnpapa/angular-styleguide#data-services) if you want something that "feel" better
2

You can store every item that the user request in a factory and then check if the content is in the factory before do 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 well as someone said you can use the $http cache but i don't know how really it works

UPDATE

A someFactory example:

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

    var storedItems = [];

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

}]);

test 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 it helps you

UPDATE2 FULL EXAMPLE CODE

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;
        }
    };

}]);

6 Comments

Your solution seems pretty cool, but can you provide me more info about how to declare the "someFactory" ? thanks again
you need to "attach" this factory to your controller in some way don't you? I'm getting an error but I think it's because I missed this part..sorry!
you need to inject it (someFactory) as a dependency of your controller like $scope or $http
@FrnndSgz see the last update with a full code example
Oooh! thanks for the full version. By the way does the $cacheFactory -provided by Angular- a similar thing? docs.angularjs.org/api/ng/service/$cacheFactory
|
1

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's set on success so the server error code would be between 200 and 299. Then you can set ng-show in view basing on $scope.wasCalled variable.


Here is implementation taking into account different id calls.

$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 specified id was called, if not, call with $http and add id to list.

1 Comment

What if you need to call it with a different id?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.