Frederik Sohnis
Frederik Sohnis

Reputation: 1095

Axios: How to intercept and respond to axios request

Is there a way to not just intercept but also respond to an axios request before it has been sent off? As in, send a request from the browser and respond to it from the browser + prevent it from sending request.

I know that I can use axios interceptors to intercept the request and response before it is sent and returned to the component and I know that in the request interceptor I can throw an error and trigger the response interceptor with a failed request. How can I do the same for a successful request? Given certain conditions I want axios to respond as if it passed to the server when it actually never made it past the interceptor. is this possible?

Here's pseudo code for what I've got so far:

      axios.interceptors.request.use(
      request => {
        if (localResponse) {
              throw { isLocal: true, data: { hello: 'world' } }; // <- this will stop request and trigger 
                                                                 // response error. I want to trigger 
                                                                 // the actual response callback
        } else {
            return request;   // <- will perform full request
        }
      },
      error => {
        return Promise.reject(error);
      }
    );

    axios.interceptors.response.use(
      response => {
        return response; // <- I want to trigger this callback
      },
      error => { // <- so far i can only trigger a response error
        if (error?.isLocal) { 
          return Promise.resolve(error.data); 
        }
        
        return Promise.reject(error);
      }
    );

I've tried just resolving the request interceptor but that tries to continue to fulfill the request. Does anyone have any creative ideas for solving this problem? Maybe there's a better solution than using interceptors?

Upvotes: 7

Views: 8113

Answers (3)

kukuh hannugroho
kukuh hannugroho

Reputation: 1

You can provide custom adapter

import axios, { getAdapter } from 'axios';

const xhrAdapter = getAdapter('xhr');

axios.defaults.adapter = (config) => {
  if (useLocal) {
    return Promise.resolve({
      data: yourData,
      status: 200,
      statusText: 'ok',
      headers: {},
      config: config,
      request: {}
    });
  }
  return xhrAdapter(config)
}

Upvotes: 0

Frederik Sohnis
Frederik Sohnis

Reputation: 1095

Managed to compose a solution myself. This way all my axios calls will not have to be altered, i can just change behavior of interceptor.

NOTE: If anyone comes up with a better solution I will happily tag their answer as correct and upvote. For now this is the best solution I can come up with.

SOLUTION

Here's how i was able to resolve the problem

      axios.interceptors.request.use(
      request => {
        if (localResponse) {
              throw { isLocal: true, data: { hello: 'world' } }; // <- this will stop request and trigger 
                                                                 // response error. I want to trigger 
                                                                 // the actual response callback
        } else {
            return request;   // <- will perform full request
        }
      },
      error => {
        return error?.isLocal 
                    ? Promise.resolve(error); // <- triggers response intercept
                    : Promise.reject(error);
      }
    );

    axios.interceptors.response.use(
      response => {
        return response; 
      },
      error => {
          error?.isLocal 
                ? Promise.resolve(error); // <- sends as successful response
                : Promise.reject(error);
      }
    );

Essentially what I'm doing is throwing an error to prevent the request from going through, but then resolving the error instead of rejecting it. It's a little hacky but it gets the job done.

Upvotes: 7

Brandon Gano
Brandon Gano

Reputation: 6710

Can you just skip the request altogether in the local scenario?

function getData() {
  if (localResponse) {
    return Promise.resolve({ isLocal: true, data: { hello: 'world' }});
  }
  else {
    return axios.whatever;
  }
}
...
getData().then(...)

Upvotes: 1

Related Questions