Making a Request on Behalf of a Component in Vue.js Using Interceptors

Within my Vue application, I've implemented a response interceptor:

axios.interceptors.response.use(function (config) {
        return config;
    }, error => {
        if (error.response.status !== 401) {
            return new Promise((resolve, reject) => {
                reject(error);
            });
        }

        if (error.response.status === 401 && error.response.data.message === 'Token Expired') {
            this.store.dispatch('auth/refreshToken').then(aToken => {
              var config = error.config;
              axios.defaults.headers.common['Authorization'] = 'Bearer ' + aToken;

              return new Promise((resolve, reject) => {
                axios.request(config).then(response => {
                  console.log(response);
                  resolve(response);
                }).catch((error) => {
                  reject(error);
                });
              });
            });
          }
    });

The focus here is on refreshing the token and reattempting the last request with the updated token.

An issue arises when considering a specific component, Product.vue. For example, a request is made to the /products endpoint upon mounting this component. The retrieved products are stored in a data variable called products. If a user is currently on the /dashboard route and their session expires while they're away, a subsequent visit to the /products route triggers a 401 response interception event. The interceptor will update the token and retry the failed request with the new token.

The challenge lies in the fact that the new API call triggered by the interceptor doesn't originate from the original Product component. As a result, any retrieved data is lost, leading to an empty view for the end-user.

Is there a method to identify the component responsible for the initial request within the interceptor and trigger a remount? Attempts such as using $router.push('/products') lead to navigation restrictions due to being already on the target route.

Alternatively, is it possible to manage the promise returned by the interceptor within the Product component?

Answer №1

To keep the promise chain running smoothly, make sure to return the dispatch promise in order to avoid any disruptions.

axios.interceptors.response.use(success => success, error => {
  if (error.response.status === 401 && error.response.data.message === 'Token Expired') {
    // Include a new promise
    // The specifics of "this" and "store" may be uncertain, but it's your code after all
    return this.store.dispatch('auth/refreshToken').then(token => {
      axios.defaults.headers.common.Authorization = `Bearer ${token}`
      return axios.request(error.config)            
    })
  }
  return Promise.reject(error)
})

In simpler terms, Axios' response interceptors are like additional steps in the promise chain that occurs before your code receives the data...

return axios.request({ ... })
  .then(successInterceptor)
  .catch(errorInterceptor)

Your focus is only on handling successful responses by directly returning the original result:

success => success

On the other hand, the error interceptor will address expired token issues by initiating a new promise, starting with token renewal followed by repeating the initial request (Promise chaining).

If the error is not related to an expired token, maintaining the rejected promise ensures consistency. Failing to do so can lead to misleading outcomes for your calling code 🙂.

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

Encountering TypeScript errors with React-Apollo when using GraphQL to pass props to a higher order component

I've encountered some challenges while attempting to link a React class component with my local Apollo cache data. Following the guidelines outlined here, I have run into issues where VSCode and Webpack are generating errors when I try to access data ...

What steps can I take to redesign my React App in order to successfully send state to a component located on a separate route?

I am currently facing a challenge with restructuring my App in order to pass state via props from the SubmitProject Component to the Portfolio Component. The catch is that I still need to maintain separate paths for each component, such as /portfolio and / ...

SmartEdit functions properly when spartacus is running using yarn start --ssl, but does not work without SSL enabled

I followed the smartedit setup instructions at and everything works well when I start the Spartacus server with yarn start --ssl. However, if I start the server with just yarn start, the storefront does not appear. See image here for reference ...

Have you ever wondered why the expression `Number(new Boolean(false))` always returns `0

In the case of Boolean(new Boolean(...)) === true, it is because new Boolean(...) is treated as an object. However, why does Number(new Boolean(false)) === 0 (+new Boolean(false) === 0) and Number(new Boolean(true)) === 1? Instead of resulting in NaN. Wh ...

The quirks of JSON.stringify's behavior

I am in the process of gathering values to send back to an ASP.NET MVC controller action. Despite using JSON.stringify, I keep encountering Invalid JSON primitive exceptions and I am unsure why. I have a search value container named searchValues. When I i ...

Guide on implementing event listener for right click using pure JavaScript (VANILLA JS)

I need the div to appear wherever the cursor is holding down the right mouse button. In my scenario, I am using the following code: <div class="d-none" id="item"></div> #item{ position: absolute; top: 0; left: 0; w ...

Error message: The function send() cannot be applied to the object received by request.post() in Node

As I embark on testing the functionalities of my node.js website using chai and mocha, I encountered an issue when running npm test. The error message displayed is: ' TypeError: request.post(...).send is not a function' Referencing the code sni ...

Optimizing with react and mobX: What You Need to Know

I am new to React and MobX and have been studying various tutorials on using both together. Currently, I am working on creating a form where users can select a product through autocomplete functionality using react-select. Once a product is selected, the i ...

Angular UI Grid failing to properly display date formatting

Currently, I am using Angular's UI Grid to showcase multiple columns. However, I am facing an issue with formatting the date column. The date is being displayed as /Date(1451346632162-0000)/, and similar formats. I have attempted to apply filters in ...

Designing personalized visualizations using elasticsearch

After setting up ELK tools, I have a desire to extract data from Elasticsearch and generate my own graphs without relying on Kibana. I've heard about tools like elasticsearch.js, but I'm unsure how to begin using it. What steps should I take in o ...

What are the steps to install the LTS release of NodeJS if Node 10 is already installed on my system?

Several weeks ago, I installed Node version 10.11 on my computer. However, a repository I am working with requires me to have the LTS version of Node, which is currently 8.12. If I download the LTS version, will it interfere with my existing install, or ...

When receiving JSON and attempting to store the data in a variable, I encounter an issue where it returns the error message "undefined is not iterable (cannot read property Symbol

I'm currently integrating the Advice Slip API into my project. I am experiencing an issue when trying to store the JSON data in a variable like so: let advice; fetch("https://api.adviceslip.com/advice").then(response => response.json()). ...

Verify the value at a specific index within a Vuelidate array

I am working with a form array in Vuelidate and I have a requirement to validate one field based on the value of another field at the same index within the array. For example, I need the forename field to be required only if the surname field has been fil ...

Tips for eliminating the backslash introduced by JQuery

Switching back from framework 4.5 to 4.0 caused several issues that needed fixing. One significant change I noticed was that jQuery started escaping double quotes. Is there a way to stop this behavior? I attempted datatest = datatest.replace("\\ ...

Using Jquery to make an Ajax request to an Asp.net Web Method

My current approach involves using a jquery method to transmit only the member identification # from the client side to the server side. On the server side, I have a traditional Web Method in place to receive the data and execute SQL queries accordingly. ...

Unable to connect Dropzone to dynamically loaded DIV using AJAX

Using Dropzone for client-side image uploads has been a breeze. Take a look at this basic example that is currently up and running: If you examine the source code, you'll notice that I am utilizing JQuery to connect Dropzone to the upload1 div ID. H ...

Exchange one HTML element with a different HTML element

I've been attempting to change an HTML tag using PHP or jQuery. The current default tag is: <li class="dropdown"> <a href="index.html" class="dropdown-toggle"> Home</a></li> My desired replacement for the above HTML tag is: ...

The list item click event is not triggered when new list items are added

I've run into a bit of confusion with my code. Everything seems to be working perfectly fine until I introduce new items. Take a look at a sample of my items However, once I make changes to my list, the click function stops working. Check out a sa ...

Issue encountered while presenting canvas on HTML due to Firebase information

Even though I believe I'm following the correct steps, I am facing an issue where the graph displaying real-time database values is not showing up. The first image shows my real-time database and a demostration as shown in images 2 and 3. While the da ...

Grabbing a section of a URL through a bookmarklet: A simple guide

Recently, I've been using this handy bookmarklet: javascript:currentUrl=document.location.href;document.location.assign(currentUrl+'embed'); This neat tool grabs the current URL, such as www.example.com/knZg_INW8fL/, and adds embed to it f ...