AngularJS Interceptors - Modify the response data to cached data

503 Views Asked by At

I'd like to create a cache solution with etags, with angular interceptors. Everything is working perfectly but I can't return the cached data. I would like to overwrite the 304 Not Modified response with the cached data.

      'responseError': function(rejection) {

          if(rejection.status === 304){
              var response = {};

              var url = rejection.config.url;
              var params = rejection.config.params || {};
              var etagKey = url+'.'+JSON.stringify(params);
              var storedValue = $localStorage['ETag-Cache'+etagKey] || '{}';
              var cachedObj = JSON.parse(storedValue);

              console.log('CACHED ETag-Cache'+etagKey,cachedObj.response);

              //I'd like to return with the cached data here but this doesn't work
              return cachedObj.response;

          }

          return $q.reject(rejection);
      }

An example request below

      $http.get('/api/bigdata', {


    }).then(function(resp){
       //I'd like to get the cached data in the resp variable
    });
1

There are 1 best solutions below

0
On

I've not found the solution but I have a workaround. Since the problem with the 304 error status, I'm sending back a status code 200 instead with a custom header: Not-Modified = 1 and an empty response, then I handle this in the interceptor.

pseudo code in Laravel ETag MiddleWare

        if ($requestEtag && $requestEtag[0] == $etag) {
            $response->setStatusCode(200);
            $response->header('Not-Modified', true);
            $response->setContent('{"status":"Not-Modified"}');
        }

AngularJS Interceptor response handler:

        //Etag Handler
        var url = res.config.url;
        var params = res.config.params || {};
        var etag = res.headers().etag;
        var etagKey = url+'.'+JSON.stringify(params);
        var EtagVal = JSON.stringify(
            {
                'etag':etag,
                'url':url,
                'params':params,
                'response':res.data
            });


        //If Not-Modified header is true
        if(res.headers()['not-modified'] == "1"){
            var storedValue = $localStorage['ETag-Cache'+etagKey] || '{}';
            var cachedObj = JSON.parse(storedValue);

            console.log('CACHED ETag-Cache'+etagKey,cachedObj.response);
            res.data = cachedObj.response;
            return res || $q.when(res);
        }

This way I can get cached value in $http.then(response) instead of downloading the whole data from the server.