Display a loading indicator while Axios sends the Ajax request

I'm currently working on a Vue app and I am utilizing Axios for API calls. Before each call, I display a loading icon that hides once the call is completed.

I'm curious if there is a way to implement this functionality globally so that I don't need to include the show/hide loading icon logic in every API call?

This is my current code snippet:

context.dispatch('loading', true, {root: true});
axios.post(url,data).then((response) => {
        // some code
        context.dispatch('loading', false, {root: true});
    }).catch(function (error) {
        // some code
        context.dispatch('loading', false, {root: true});color: 'error'});
    });

I have come across information about "interceptors" in the Axios documentation but I am unsure whether they apply at a global level or are specific to each call.

I also found a jQuery solution in a post, but I am not sure how to adapt it for use in Vue:

$('#loading-image').bind('ajaxStart', function(){
    $(this).show();
}).bind('ajaxStop', function(){
    $(this).hide();
});

Answer №1

To implement Axios interceptors in Vue.js, you can set them up within the root component's created lifecycle hook, such as in the App.vue file:

created() {
  axios.interceptors.request.use((config) => {
    // Implement loading=true functionality here
    return config;
  }, (error) => {
    // Implement loading=false functionality here
    return Promise.reject(error);
  });

  axios.interceptors.response.use((response) => {
    // Implement loading=false functionality here
    return response;
  }, (error) => {
    // Implement loading=false functionality here
    return Promise.reject(error);
  });
}

Managing the global loading state while handling multiple concurrent Axios requests requires tracking the request count. To do this, increment the count on each request, decrement it when the request resolves, and clear the loading state when the count reaches 0:

data() {
  return {
    refCount: 0,
    isLoading: false
  }
},
methods: {
  setLoading(isLoading) {
    if (isLoading) {
      this.refCount++;
      this.isLoading = true;
    } else if (this.refCount > 0) {
      this.refCount--;
      this.isLoading = (this.refCount > 0);
    }
  }
}

For a demonstration of this setup, you can check out this demo.

Answer №2

It seems like you're heading in the right direction by using dispatch event when ajax calls start and finish.

To achieve this, you can intercept the XMLHttpRequest call using axios interceptors as shown below:

axios.interceptors.request.use(function(config) {
  // Perform actions before sending the request
  console.log('Start Ajax Call');
  return config;
}, function(error) {
  // Handle errors with the request
  console.log('Error');
  return Promise.reject(error);
});

axios.interceptors.response.use(function(response) {
  // Perform actions with the response data
  console.log('Done with Ajax call');

  return response;
}, function(error) {
  // Handle errors with the response
  console.log('Error fetching the data');
  return Promise.reject(error);
});

function getData() {
  const url = 'https://jsonplaceholder.typicode.com/posts/1';
  axios.get(url).then((data) => console.log('REQUEST DATA'));
}

function failToGetData() {
  const url = 'https://bad_url.com';
  axios.get(url).then((data) => console.log('REQUEST DATA'));
}
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<button onclick="getData()">Get Data</button>
<button onclick="failToGetData()">Error</button>

Answer №3

Utilizing Nuxt alongside the $axios plugin

modules: ['@nuxtjs/axios', ...]

plugins/axios.js

export default ({ app, $axios ,store }) => {
  const token = app.$cookies.get("token")
  if (token) {
    $axios.defaults.headers.common.Authorization = "Token " + token
  }
  $axios.interceptors.request.use((config) => {
    store.commit("SET_DATA", { data:true, id: "loading" });
    return config;
  }, (error) => {
    return Promise.reject(error);
  });

  $axios.interceptors.response.use((response) => {
    store.commit("SET_DATA", { data:false, id: "loading" });
    return response;
  }, (error) => {
    return Promise.reject(error);
  })
}

store/index.js


export default {
  state: () => ({
    loading: false
  }),
  mutations: {
    SET_DATA(state, { id, data }) {
      state[id] = data
    }
  },
  actions: {
    async nuxtServerInit({ dispatch, commit }, { app, req , redirect }) {
      const token = app.$cookies.get("token")
      if (token) {
        this.$axios.defaults.headers.common.Authorization = "Token " + token
      }
      let status = await dispatch("authentication/checkUser", { token })
      if(!status) redirect('/aut/login')
    }
  }
}

Illustrating a process involving token validation using $axios and store management

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

Error: The jQuery TableSorter Plugin is unable to access property '1' as it is undefined

I've been attempting to utilize the jquery table sorter plugin, but I keep encountering an error when trying to sort the table. The error message I'm receiving is: cannot read property '1' of undefined This is the HTML code I have: ...

Facing challenges in both client-side and server-side components

import axios from 'axios'; import Image from 'next/image'; export const fetchMetadata = async({params}) => { try { const result = await axios(api url); return { title: title, description: Description, } / } catch (error) { con ...

I am interested in incorporating pinia state management into my Vue 3 project

I'm currently working on implementing pinia state management in Vue 3, but I've encountered the following error: Module not found: Error: Can't resolve 'src/stores/cart' in 'C:\Users\Ali Haider\theme-project&b ...

Changing the CSS class of the Bootstrap datetime picker when selecting the year

Is there a way to change the CSS style of the Bootstrap datetime picker control so that when selecting years, the color changes from blue to red? I attempted to do this with the following code: .selectYear { background-color:red!important; } However ...

I'm currently attempting to determine the total cost of a series of operations, however, I am not receiving any results

Here is the code snippet from my HTML file: <tr> <td><input id="z1" type="number" oninput="calculateSubTotal()"> </td> <td>Shirts - WASH - Qty 1 to 4</td> <td>2.50 ea</td> ...

Issue encountered with the style parameter in print-js when attempting to print from a Vue.js component

While browsing the print-js documentation, I came across a feature that allows us to pass style as a string to the printJS function. However, when attempting to apply this style, I encountered an error preventing the print action: The error I'm facin ...

Unable to access $_POST parameters in PHP when making an Ajax request

My HTML file is shown below: <script> var xml = new XMLHttpRequest(); xml.onreadystatechange = function(){ if (xml.readyState === 4 && xml.status === 200) { console.log(xml.responseText); } } xml ...

Router DOM in conjunction with Next.js

I am attempting to extract the output of the code in navigation, but unfortunately it is generating a dreadful error: Unhandled Runtime Error Error: You cannot render a <Router> inside another <Router>. You should never have more than one in ...

Insert a numerical value into a list to make a series of numbers whole

I currently have an array of objects that looks like this: var arr = [ { "code": "10", }, { "code": "14", } ] My goal is to expand this array to contain 5 elements. The numbers should ran ...

Learn the simple steps to duplicate events using ctrl, drag, and drop feature in FullCalendar v5 with just pure JavaScript

My goal is to incorporate CTRL + Drag & Drop functionality in FullCalendar v5 using nothing but pure JavaScript. I delved into the topic and discovered that this feature has been discussed as a new UI feature request on the FC GitHub repository. There ...

Adjust the HTML content prior to displaying it to prevent any flickering

Is there a way to run code before the page is rendered, such as updating dates or converting text to HTML, without causing flickering when reloading multiple times? How can I ensure the code runs as it's drawn instead of waiting until the end to redra ...

Is it beneficial to vary the time between function calls when utilizing setInterval in JavaScript?

My website is displaying two words one letter at a time, with a 0.1s delay between letters and a 3s pause after each full word. I attempted using setTimeout, but it's not functioning as expected. What could be the issue in my code? var app = angular. ...

Is there a way to disable page prefetching for Next.js Link when hovering over it?

Whenever a link is hovered over in my production application, an XHR request is sent to the server. I need to find a way to prevent this from happening. I tried using prefetch={false} but it didn't work. Any suggestions on how to resolve this issue? ...

"Troubleshooting: Issue with the custom rule 'isBetween' validation in Vee validate

I am working on validating text fields and attempting to create multiple rules such as required, minlength, maxLength, and chaining them together. Depending on which parameter is passed, the validation should be performed. While working on this, I referre ...

HTML stubbornly resists incorporating Javascript [UIWebView]

Currently, I am facing an issue while trying to animate a color property using jQuery 1.7.1 and the jquery color plugin downloaded from this link. I have ensured that all necessary files are included and part of the build target. Here is a simplified versi ...

Adjust the location of the slider scrollbar in jQuery UI

Currently, I am implementing jQuery UI's slider scrollbar and my goal is to set its position upon page load. Although I have referred to the sample code provided, my experience with jQuery UI is limited, so I am unsure about the necessary modification ...

Output JSON data from PHP for use in Javascript

Is there a way to effectively convert JSON data from PHP/Laravel into JSON for JavaScript? I have the JSON string from PHP, but it is only rendering as a string. How can I convert it to a JSON object in JavaScript? Take a look at my code below. $('#e ...

MapBox notifies when all map tiles have finished loading

Currently, I am utilizing the Mapbox GL JS API to manipulate a Mapbox map. Prior to sending my result (which is a canvas.toDataURL) to the server via HTTP, I must resize my map to a larger resolution and then use fitbounds to return to the original points. ...

Strange behavior of Lambda function in Typescript

Within a larger class, I'm working with the following code snippet: array.map(seq => this.mFunction(seq)); After compiling using the tsc command, it becomes: array.map(function (seq) { return _this.mFunction(seq); }); Everything seems fine so f ...

Steps for accessing the "this" keyword within the parent function

Struggling with referencing `this` within a parent function while building a basic tab system using AngularJS. It seems like I may not have a solid grasp on the fundamentals, so any guidance would be appreciated: JavaScript: $scope.tabs = { _this: th ...