Reputation: 1095
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
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
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
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