Until now, I had been importing axios in each Vue component where I wanted to make HTTP requests, like this.
<script lang="ts">
import axios from 'axios';
@Component
export default class ExamplePage extends Vue {
created(): void {
axios.post(some_path);
}
}
However, now I want to define a global interceptor for all axios requests, basically to catch all 401 unauthorized
responses from the backend server (Rails) and log out the user.
My understanding so far is that you must instantiate axios once and use it everywhere, instead of importing and using a different instance in each file.
I've referred to this and this, and tried the below.
// application.js
import '../assets/sass/base.sass';
import App from '../app';
import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';
import router from '../routes';
Vue.use(VueRouter);
document.addEventListener('DOMContentLoaded', () => {
new Vue({
el: '#application',
router,
render: (h) => h(App),
});
});
axios.interceptors.response.use(
response => response,
error => {
const status = error.response;
if(status === 401) {
// do stuff
}
}
);
Vue.prototype.$http = axios
When I tried to call this.$http.put(...)
in another file, it said property $http
doesn't exist (I'm guessing it's because this
in the context of that component is the component itself, but I'm not sure). How can I fix this?
[UPDATE] Thanks to the responses, I decided to initialize an axios instance in a separate file and then use that instead. However, this is still not working. The 401 responses don't seem to be triggering the interceptor at all.
Is there some additional configuration necessary?
// axios-instance.ts
import axios, { AxiosInstance } from 'axios';
const axiosInstance: AxiosInstance = axios.create();
axiosInstance.interceptors.response.use(
response => response.data,
async function(error) {
console.log("THIS IS THE 401 INTERCEPTOR")
const status = error.response;
if(status === 401) {
// Log out user
}
}
);
export default axiosInstance;
// Some component
<script lang="ts">
import axiosInstance from 'axios-instance';
@Component
export default class ExamplePage extends Vue {
created(): void {
axiosInstance.post(some_path);
}
}
this.$http.interceptors
inapplication.js
, you'd need to useaxios.interceptors
. If that isn't the cause of your problem could you please update your question to include the call toput
that isn't working. Without some context it's difficult to tell whether you're doing that correctly or not. – skirtleaxios
, but when I try to call it in any other files it still goes "Property '$http' does not exist on type 'ExamplePage' (name of component)". As I wrote above, it's probably becausethis
in the context of that component refers to the component itself. Further advice appreciated. – reesaspiecesconst status = error.response;
, which should probably beconst status = error.response.status;
. The error handler also isn't returning a rejected promise, which may prove problematic. – skirtle