0

I have an AngularJS function, that loads data from a webservice and then stores it in the localStorage. After calling this function the first time, the data should be loaded from localStorage (unless the cache is invalid after an hour).

I would like to externalize this function, but I'm scratching my head, how to put a sync and an async call into one method. Here we go.

function callWebService(url) {
    var resultFromLocalStorage = localStorage.getItem(url);
    if (resultFromLocalStorage && Utils.cacheIsStillValid()) { //(*)
        $timeout(function() { buildTable(JSON.parse(resultFromLocalStorage)); }, 10);
    } else {
        $resource(url).get().$promise.then(function(result) {
            localStorage.setItem("cacheExpiry", new Date().getTime() + Utils.ONE_HOUR_IN_MS);
            localStorage.setItem(url, JSON.stringify(result));
            buildTable(result);
        });
    }
}
//*Utils.cacheIsStillValid checks the localStorage item "cacheExpiry"

I would like to externalize that caching stuff, so in the end, I just want this:

function callWebService(url) {
    var result = getResultFromCacheOrReload(url); // to be done
    buildTable(result);
}

How can I do this? How would the method getResultFromCacheOrReload(url) look?

Thanks, Bernhard

2
  • You should leave the caching to the pro's. Tell the browser to cache it by setting etags. Commented Dec 2, 2016 at 8:28
  • Thanks for your response. Unfortunately I am not allowed set etags on our servers. Commented Dec 2, 2016 at 10:30

1 Answer 1

1

Simply return a promise from getResultFromCacheOrReload and build the table when it is resolved:

function callWebService(url) {
    var result = getResultFromCacheOrReload(url).then(function (result) {
        buildTable(result);
    });
}

The function getResultFromCacheOrReload can be something like:

function getResultFromCacheOrReload(url) {
    var resultFromLocalStorage = localStorage.getItem(url);
    if (resultFromLocalStorage && Utils.cacheIsStillValid()) {
        return $q.when(resultFromLocalStorage); // Create a fulfilled promise containing  resultFromLocalStorage
    } else {
        return $resource(url).get().then(function (result) { // Return the promise returned by the "then" method
            localStorage.setItem("cacheExpiry", new Date().getTime() + Utils.ONE_HOUR_IN_MS);
            localStorage.setItem(url, JSON.stringify(result));
            return result; // Every object returned by a then() method is wrapped by a promise
        });
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that was (almost) it. I just had to modify this line: return $resource(url).get().then(...) with return $resource(url).get().$promise.then(...) Now it works.

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.