Search code examples
javascriptjqueryajaxmemoization

How to memoize jquery ajax response?


I want to cache the jQuery AJAX response so that I don't need to make the network call again.

Below is my JS code:

$(".btn").on("click", function(){
    var id = $(this).data("id");
    var url = "https://alert-carpenter.glitch.me/api/movies/"+id;
    var loadData = memoize(getDataById);

    var data = loadData(url);
    console.log(data);
    // $("#title").html(data.data.title);

});

function getDataById(url,cache){
    $.ajax({
        method:"GET",
        url: url,
        success:function (data){
            console.log("ajax data", data);
            console.log("cache",cache);
            cache[url] = data;     
        }
    });
}

function memoize(fn){
    var cache = {}

    return function(url){
        if(cache[url]!=undefined){
            console.log("loading from cache");
            return cache[url];
        }else{
            console.log("loading from server");
            fn(url,cache)

            return cache[url];
        }
    }
}

AJAX call is getting the response but is it not updating the cache response.

I know if i make Cache variable as global then i can simply update it in jquery ajax success function. but i dont want to make the Cache global.

so here I'm trying to use closure. Please correct me if there is any mistake.


Solution

  • The problem is that you are memoizing the function every time you respond to the button press. You have

    $(".btn").on("click", function(){
        //...
        var loadData = memoize(getDataById);
        ... loadData(input) ...
    });
    
    
    function memoize(fn){
        var cache = {}
    
        return function(url){
            if(cache[url]!=undefined){
                console.log("loading from cache");
                return cache[url];
            }else{
                console.log("loading from server");
                fn(url,cache)
    
                return cache[url];
            }
        }
    }
    

    So when you call memoize it is constructing a new closure with access to a new cache and returning that. Try creating the memoized loadData outside instead:

    var loadData = memoize(getDataById);
    
    $(".btn").on("click", function(){
        //...
        ... loadData(input) ...
    });
    

    That way it's the same closure with the same cache that gets called several times.