How to cache API responses in front-end in Angular…

Published by Shubham Srivastava on

Frontend caching

API Responses in angular are usually handled by a custom data type used by angular called “Observable”. Using this angular makes sure the result is synchronized with the asynchronous API calls.

There is no direct way to save an Observable variable value in browser cache storages. So, we will use simple logic to build a way around that.

A brief description of “Observable”

Angular makes use of observables as an interface to handle a variety of common asynchronous operations. For example:

  • You can define custom events that send observable output data from a child to a parent component.
  • The HTTP module uses observables to handle AJAX requests and responses.
  • The Router and Forms modules use observables to listen for and respond to user-input events.

What to do?

Storing any data in frontend can be performed by using various storage options provided by browsers like localStorage, sessionStorage, cookies, indexedDB, etc. We will use localStorage of browsers in this exercise as it is supported by most of the modern-day browsers.

Why to do?

Before starting on how to perform this task, we will look at a use case as to why and where do we need to even to do this.

Applications like Fibotalk allows the loading of many analytics charts at once.

In spite of throwing all analytics calculation APIs at once which puts a great load on the server when there are 100s or 1000s of users opening this at once, you can implement caching to save the data once loaded in the frontend only.

Implementing caching will almost negate this load as there is now on-demand basis analytics. With this, you could now handle even 1000s or 10000s of users’ load with not much cost.

How to do?

As I said earlier, we used localStorage to perform this exercise.

In Angular, we need two functions — one to store and another to retrieve,

/**
 * Get cached data if available and required
 * @param cacheStat : Caching status object containing decision
 * cacheStat: { cache: true, save: true, key: "", data: {} }
 */
getCache(cacheStat): Observable<any> {
    try {
        if (!(cacheStat.cache && cacheStat.key))
            return null;let id = sessionStorage.getItem("id");
        if (cacheStat.data) {
            localStorage.setItem(`${id}:${cacheStat.key}`, cacheStat.data);
            return of(cacheStat.data);
        }let data = {};
        try {
            data = JSON.parse(localStorage.getItem(`${id}:${cacheStat.key}`));
        if (!data)
            return null;
        } catch (error) {
            return null;
        }
        return of(data) || null;
    } catch (error) {
        return null;
    }
}/**
 * Set API response in cache as per need
 * @param cacheStat : Caching status object containing decision
 * @param resp : The Observable response from BE
 * cacheStat: { cache: true, save: true, key: "", data: {} }
 */
setCache(cacheStat, resp: Observable<any>) {
    try {
        if (!(cacheStat.key && cacheStat.save))
            return;resp.subscribe(
            resp => {
                console.log("response data", resp)
                if (resp.statusCode == 200) {
                    resp.ts = Date.now();
                    let id = sessionStorage.getItem("id");
                    localStorage.setItem(`${id}:${cacheStat.key}`, JSON.stringify(resp));
                }
            },
            error => {
                console.log("response data", error)
            }
        );
    } catch (error) {}
}resp.subscribe(
        resp => {
          console.log("response data", resp)
          if (resp.statusCode == 200) {
            resp.ts = Date.now();
            let gid = sessionStorage.getItem("gid");
            localStorage.setItem(`${gid}:${cacheStat.key}`, JSON.stringify(resp));
          }
        },
        error => {
          console.log("response data", error)
        }
      );
    } catch (error) {}
  }

Leave a Reply

Your email address will not be published. Required fields are marked *