Invoking Vuex mutation inside an Axios interceptor

Is it possible to trigger a mutation from an interceptor in Vue? Specifically, I want to trigger the logout mutation whenever Axios encounters an http 403 error.

I have imported Vuex mutations and mapped them as I usually do, but I am struggling to access them within the Axios interceptor error function. I have added my interceptor configuration in the created() method of App.vue.

I have attempted solutions from other sources without success, possibly because my project uses modules and the Axios config is within a created() method.

  1. This Reddit thread discusses Axios config in a separate file - is this recommended?
  2. This Stack Overflow question addresses accessing Vuex storage mutation inside Axios interceptor without using modules.

App.vue

<script>
import { mapMutations } from "vuex";
import axios from 'axios';
export default {
  methods: {
    ...mapMutations(["logout"])
  },
  created(){
    axios.interceptors.response.use(
      function (response) {
        return response;
      }, 
      function (error) {
        if (error.response.status === 403) {
          this.logout()
            .then(() => {
              this.$router.push("/");
            })
        }
    });
  }
}
</script>

EDIT Here is a screenshot of the results based on the provided answers: https://i.sstatic.net/uryJP.png

Answer №1

You're almost there. The key issue is that you were defining functions using the function() {} syntax instead of the "fat-arrow" function syntax, which was creating a different scope (this was affected). Take a look at the comparison between the two approaches below.

// Original script
import { mapMutations } from "vuex";
import axios from 'axios';
export default {
  methods: {
    ...mapMutations(["logout"])
  },
  created(){
    axios.interceptors.response.use(
      function (response) {
        return response;
      }, 
      function (error) {
        if (error.response.status === 403) {
          this.logout()
            .then(() => {
              this.$router.push("/");
            })
        }
    });
  }
}

// Updated version
import { mapMutations } from "vuex";
import axios from 'axios';
export default {
  methods: {
    ...mapMutations(["logout"])
  },
  mounted() {
    axios.interceptors.response.use(
      (response) => response, 
      (error) => {
        if (error.response.status === 403) {
          return this.logout()
            .then(() => this.$router.push("/"));
        }
        else {
          return Promise.reject(error);
        }
    });
  }
}
</script>

Answer №2

To correctly access `this`, you will need to either utilize an arrow function or bind the this context to your function.

<script>
import { mapMutations } from "vuex";
import axios from 'axios';
export default {
  methods: {
    ...mapMutations(["logout"])
  },
  created(){
    axios.interceptors.response.use(
      function (response) {
        return response;
      }, 
      (error) => {
        if (error.response.status === 403) {
          this.logout()
            .then(() => {
              this.$router.push("/");
            })
        }
      }
    );
  }
}
</script>

or

<script>
import { mapMutations } from "vuex";
import axios from 'axios';
export default {
  methods: {
    ...mapMutations(["logout"])
  },
  created(){
    axios.interceptors.response.use(
      function (response) {
        return response;
      }, 
      function (error) {
        if (error.response.status === 403) {
          this.logout()
            .then(() => {
              this.$router.push("/");
            })
        }
      }.bind(this)
    );
  }
}
</script>

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

The issue arises when attempting to populate the Facebook login window after clicking the 'like' button in Selenium webdriver

Hey there, I need help with a HTML snippet. I'm trying to click on the Facebook icon and open a popup window, but when I use Selenium's click action, no error is displayed, yet the popup window doesn't appear. If you have any solutions, ple ...

Is there a way to trigger a CSS3 animation to play when scrolling down and then play in reverse when scrolling up?

Using a blogger website, I have successfully set up sticky navigation. However, when scrolling back up, the navigation bar pops back into place without any animation. I am looking for a solution to smoothly return the navigation bar to its original positio ...

Tips for incorporating the "build" directory into the Travis-CI build process and deployment of an npm module

Currently, I am working with a Typescript module that has a directory ./src And I also have travis-ci set up for the project. language: node_js node_js: - 5.1.0 install: - npm install - npm install -g mocha - npm install -g gulp - npm install -g tsd - ...

Route fallback not yet resolved

Is it possible to set up a fallback route in angular routes? For instance, is there a way to specify a fallback route like this: $routeProvider .when('/a', { templateUrl: 'a.html', controller: 'aCtrl' ...

Using a JavaScript onclick function to retrieve specific elements within the document

I'm attempting to extract the elements from the source that was clicked on, but for some reason it's not functioning correctly. Check out my JSFIDDLE Here's the HTML: <span class="populate" onclick="populate();" href="?id=1">Hello&l ...

Modifying the style of a specific row when the form is submitted

My webpage contains nested records, with each nested record displaying a total number of clicks in a div labeled "count". I am looking to increment the count by 1 for each specific record when the button with a class of view is clicked. Currently, clicking ...

The functionality of if and else statements within local storage is not functioning as

I've been working on implementing a styleswitcher for my website. I successfully created a dropdown menu and saved it in localstorage. However, I'm facing an issue when trying to use the localstorage information to trigger an alert() through if a ...

Preloading not working in Bootstrap Ajax Tabs

I've encountered an issue with Bootstrap Tabs and Jquery in my Asp.net MVC5 web app. Tab 1 (30days) is not loading on page load despite my efforts to troubleshoot the code multiple times. Could someone please review and identify where I may be going w ...

Limitations of jQuery: onClick function not transferable

I am struggling to achieve the following functionality for my navbar dropdown menus: When the screen size is greater than 992px, I want the navbar dropdowns to open on mouse enter. For screens smaller than 992px, I want the dropdowns to open on ...

Vue.js is unable to render the template using Object

During this demonstration at https://jsfiddle.net/ccforward/fa35a2cc/, I encountered an issue where the template could not render and the data in resultWrong remained empty with a value of {} At https://jsfiddle.net/ccforward/zoo6xzc ...

What is the process for checking the selected option, retrieving an array value, and displaying it in a div by clicking a button?

The query may seem a bit unclear, but I will do my best to explain. Here is the HTML code snippet: <div id="buttonholder"> <button id="previous">< Previous round</button> <button id="next">Next round ></button> ...

Styling Icons for Tabs in Material UI

I am dynamically using these tabs: <Tabs value={value} onChange={handleChange} variant="scrollable" scrollButtons="off" indicatorColor="primary" textColor="pr ...

Leveraging a partial view across two different perspectives

I am working with a PartialView that is used in two different views, each utilizing its own viewmodel. On one of the views, the code looks like this: view1: @model StudentsViewModel ...... ..... @Html.Partial("_StudentOtherInformation") PartialView @mo ...

how to open a new tab using JavaScript with Selenium

My code is supposed to open a new window that goes from the login window to the main menu, module, reports, and finally the report name. The report name should be opened in the next tab. Issue: The report name is not opening in a new tab; it's openin ...

Unable to display Boostrap modal upon clicking href link

Can someone help me troubleshoot why my pop modal is not displaying after a user clicks on a specific link on my webpage? I have attempted the following: <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></s ...

How can I retrieve all the completed tasks using the Todoist API?

For my personal data tracking, I am utilizing the Todoist REST API. However, it appears that the API only permits fetching active tasks. Is there a way to retrieve completed tasks as well? I have considered using filters to achieve this, but unfortunately ...

Guide to displaying the object response on the UI in a ReactJS application

The response received from the backend looks like this: dept: Object { Sales: 33, Market: 12, Finance: 22, Hr: 26 } In my model.ts file: export default interface Dept{ categories: Record<string,number>; } Within the component: interface ...

How can I use Express.js to send an image file instead of a binary file?

When dealing with a React request in express, I am encountering an issue where I receive the image binary file instead of the actual image file as a response. I have attempted using methods such as res.sendFile and res.download to send the image, but they ...

Issue: ui-route failing to function properly when the href attribute is utilized

I am currently working on implementing ui-route to manage the states of my app while focusing on URL navigation. My goal is to enable users to simply click on a link and be directed to the state associated with the specific URL. After following an In-Dep ...

NodeJS Fork - React each instance a new line is detected from the child process

I am currently working on creating a NodeJS function (on Windows7) that listens to a subprocess and handles each newline sent through the subprocess in Node. The following example demonstrates this: var express = require('express'); var app = ex ...