Search code examples
javascriptaxioslocal-storageinterceptor

Can I use axios interceptors to replace an API request with local storage data?


I have an api client in my application with some interceptors:

const api = new OpenAPIClientAxios({...})
const client = api.initSync()
client.interceptors.request.use(...)
client.interceptors.response.use(...)

I want to write a request interceptor that will check for some data in local storage. If the data is present, I would like to not make a request at all, rather, simply respond with the local storage data.

Is this possible? Or am I misusing interceptors?


Solution

  • Interceptors can only be used to manipulate the configuration of requests and responses. Unfortunately, you cannot bypass a request entirely with them.

    Axios does provide an adapter config which...

    allows custom handling of requests

    Using this, you can create an Axios instance with a custom adapter to intercept requests and provide responses using local data.

    // mock localStorage
    const localStorage = {s:{},setItem(k,v){this.s[k]=v},getItem(k){return this.s[k]??null}};
    // mock OpenAPI client
    const client = /* api.initSync() */ axios.create({ baseURL: "https://jsonplaceholder.typicode.com/" });
    
    const wrapper = axios.create({
      adapter: ({ adapter, ...config }) => {
        const data = JSON.parse(localStorage.getItem("data"));
        if (data) {
          // return a valid response
          return Promise.resolve({
            data,
            config,
            status: 200,
          });
        }
        
        // otherwise pass-through to the real client
        return client(config);
      }
    });
    
    (async () => {
      // with no data present
      console.log("no local data:", (await wrapper.get("/todos/1")).data);
    
      // with local data
      localStorage.setItem("data", JSON.stringify({ foo: "FOO" }));
      console.log("with local data:", (await wrapper.get("/todos/1")).data);
    })();
    .as-console-wrapper { max-height: 100% !important; }
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>