Having trouble making axios a global instance in my Vue project

Previously, I used to import axios in each Vue component separately when making HTTP requests. An example of this can be seen below:

<script lang="ts">
import axios from 'axios';

@Component
export default class ExamplePage extends Vue {
  created(): void {
    axios.post(some_path);
  }
}

However, I have now realized the importance of setting up a global interceptor for all axios requests. This would help in handling 401 unauthorized responses from the backend server (Rails) and logging out the user accordingly.

According to my research on Stack Overflow and similar articles, I attempted the following approach.

// 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

Even after trying to call this.$http.put(...) in another file, I encountered an issue where the property $http was not recognized. It seems that the context of the component might be causing this problem, but I'm unsure how to resolve it. Any suggestions?

[UPDATE] Following the advice received, I attempted initializing an axios instance in a separate file. However, I am still facing issues as the 401 responses are not triggering the interceptor as expected.

Do I need to include additional configurations? Any insights would be appreciated.

// 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);
  }
}

Answer №1

Not the direct solution to your question, but a different approach I use to create an axios instance:

// custom-axios-instance.js

import axios from 'axios'

const customInstance = axios.create({
  baseURL: 'https://example-api.com/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

export default customInstance

Simply import this instance in your application file:

// app.js

import axios from '../../custom-axios-instance'

Answer №2

When outside of the Vue instance, using this is not possible. Follow these steps instead:

// 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);

axios.interceptors.response.use(
  response => response,
  error => {
    const status = error.response;
    if(status === 401) {
      // perform actions
      }
    }
  }
);

Vue.prototype.$http = axios;

const VueInstance = new Vue({
    el: '#application',
    router,
    render: (h) => h(App),
});

After this setup, you can execute HTTP requests by utilizing this.$http:

<script>
    export default {
        methods: {
            fetchData() {
                this.$http.post('path_to_post_request').then(({ data }) => {
                    // handle received data
                }).catch((e) => {});
            }
        }
    }
</script>

Answer №3

Dealing with a similar issue has brought to my attention the importance of properly handling error responses in Axios API documentation.

A suggested approach for intercepting error responses is as follows:

axios.interceptors.response.use(function (response) {
  // This function handles successful responses
  return response;
}, function (error) {
  // Here lies the key, the error callback where error responses are handled
  // It's essential to address any request errors here
  // Tip: Utilize error.response to access the response containing the error code
  return Promise.reject(error);
})

This crucial aspect is detailed in the Interceptors section of the official Axios API Documentation

Answer №4

To improve your code structure, my suggestion is to create a separate JavaScript file for the axios instance:

// utilities/axiosInstance.js

import axios from 'axios'

const api = axios.create({
  baseURL: '',
  headers: {},
  withCredentials: true,
  // ...other options
})

// Request Interceptor
api.interceptors.request.use(config => {
  // ...
  return config
}, error => {
  return Promise.reject(error)
})

// Response Interceptor
api.interceptors.response.use(response => {
  // ...
  return response
}, error => {
  return Promise.reject(error)
})

export default api

Once you have this set up, you can make HTTP requests as follows:

import axiosInstance from '@/utilities/axiosInstance'

axiosInstance({
  url: '',
  method: 'post',
  data: {}
}).then(response => {
  // Handle successful response here
}).catch(error => {
  // Handle failed response here
})

Answer №5

Consider utilizing a service:

src / services / myservice.js

import axios from 'axios'

const apiClient = axios.create({
    baseURL: 'https://sample.com/api',
    withCredentials: false,
    timeout: 2000,
   
    headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + btoa('api_key_here' + ':' + 'api_secret_here')     
    }
})

export default {
    retrieveOrders(){
        return apiClient.get('/orders?status=processing')
    },
    fetchProducts(id){
        return apiClient.get('/products/' + id)
    },
}

Incorporate the service into a Component: src / component / mycomponent.vue

import MyService from '@/services/MyService.js';
data() {
    return {
        orders: null, //JavaScript
    }
},
created() {
    myservice.retrieveOrder(id).then(response => {
        this.orders = response.data 
    }).catch(error => {
        console.log(error) 
    });
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with ESLint: Unexpected token found in JavaScript when converting to a dictionary

I've implemented a JavaScript code snippet that loops through an array of fields to find specific properties and then adds them to a dictionary. For another example, you can check out this site. return this.getFields() .reduce((mappings, field) =& ...

Query regarding timing in JavaScript

I recently started learning JavaScript and I am facing a challenge with running a check to determine if it is daylight. Currently, I am using Yahoo's weather API to retrieve information about sunrise and sunset times. The issue I have encountered is h ...

Obtaining the current value with each keystroke

While working with vue.js, I'm building a table that contains an input field called quantity. However, when I start typing the first word, it shows 'empty' on the console. If I type 3, it displays empty; and if I type 44, it prints 4. I am ...

Is there a way to update a field or submit a form without having to redirect or refresh the page?

I am struggling to find the right solution for updating just one field in my database called Flag, which is a Boolean field. I have tried using ajax/JQuery, but it only works for the first item in the list and stops working for subsequent items. The ID and ...

The extended interface appears to be lacking the implementation of parent members

I am facing an issue with two interfaces export interface IComponent{ type: ComponentType; name: string; isEnabled:boolean; } export interface IAudioComponent extends IComponent { source: string; volume: number; loop: boolean; ...

Saving a single ID at a time in a UseState array by clicking in ReactJS

When clicking on the "click here" button, I am trying to save favorite post IDs in an array. However, the issue is that it is currently only saving one ID at a time in the array. Every time you click on another "click here" button, it removes the previous ...

"We are experiencing issues with the app.get function and it is

Although my backend is successfully serving other files, I have encountered an issue with loading new files that are located in a folder named js within the directory. These specific files are not being loaded, and despite spending an hour trying to troubl ...

How can I create an event that is specific to only one element in Vue.js?

I am currently facing an issue with Vue events attached to looped elements. My challenge lies in displaying CRUD actions on individual items. Currently, all looped items display their own set of CRUD actions. Is there a way to make these actions unique t ...

Activate Pop-up for a single instance on BigCommerce

After researching and adding my own code, I am still struggling to get this question answered correctly. Here are the key points I am trying to achieve: 1. Automatically open a popup when the homepage loads. 2. Ensure that the popup is centered on all brow ...

Error with JSON parsing in JavaScript when processing large numbers

After requesting a list of approved tweets from a webserver in JSON format, I visited the URL: http://localhost:8000/showtweets/?after_id=354210796420608003 and received the following JSON response: [{ "date": "2013-07-08T12:10:09", "text": "#R ...

Is the "Angular is not functioning" error message the result of a missing import?

Encountering an 'is not a function' error in Angular 7 / TypeScript 3, using an EventEmitter. This issue has been extensively discussed (a b), but solutions have not garnered many upvotes (a b c d e f). I am close to resolving it, but need s ...

Top method for removing quotation marks from form input using jquery

Here is a form input that I need to handle: <tr class="formulaRow"> <input type="text" class="ingredient required" name="ingredient"> </tr> Currently, the value from this input is stored as follows: var ingredient = $(".formulaRow").fi ...

React-Router failing to properly unmount components when the location parameter changes

I'm struggling with a frustrating issue - I have a simple app created using create-react-app and I'm utilizing React-Router. JSX: <Router> <Route path="/pages/:pageId" component={Page} /> </Router> Within the Page ...

Problems Arising with Javascript Animation Functionality

I've created a script for an interactive "reel" that moves up or down when clicking on specific arrow buttons. However, I'm encountering two issues: 1) The up arrow causes it to move downward, while the down arrow moves it upward. 2) After exe ...

Tips for troubleshooting objects within an Angular template in an HTML file

When I'm creating a template, I embed some Angular code within my HTML elements: <button id="btnMainMenu" class="button button-icon fa fa-chevron-left header-icon" ng-if="(!CoursesVm.showcheckboxes || (CoursesVm.tabSelected == 'curren ...

Refreshing React Arrays

I have successfully created a button that deletes an element from an array. However, I am now attempting to add another button that will reload the array and show the original elements along with the deleted one. My goal is to clone the array and utilize ...

Js: Automatically populating data into various input fields

I've encountered an issue with form input value injection using a <script> and POST requests. When I attempt to create another form with the same input field (same name and id), the value injection doesn't work, and troubleshooting has bee ...

Intermittent Cloudfront Content Delivery Network (CDN) disruptions (monitoring) - Implementing CDN Fail

Over the past two months, I've been dealing with sporadic issues involving Amazon Cloudfront. These failures occur 2-3 times a week, where the page will load from my web server but assets from the CDN linger in pending status for minutes at a time. It ...

Omit the checkbox for children when clicking

I am encountering a problem with the following HTML code: <tr class="clickable" onclick="location.href='https://www.w3schools.com'"> <td> Lore ipsum </td> <td>More content</td> <td>< ...

What is the best way to combine individual function declarations in TypeScript?

In my project, I am currently developing a TypeScript version of the async library, specifically focusing on creating an *-as-promised version. To achieve this, I am utilizing the types provided by @types/async. One issue I have encountered is that in the ...