0

Goal here is to show the LOGIN modal when the API returns status 401

We have added a component in main.js

var vm = new Vue({
    el: '#app',
    router,
    store
});

Vue.component('login-modal', 
  () => import('./components/LoginModal')
)

In main.js using axios.interceptors.response.use( to check the status of all ajax requests. Works fine but now need to call the function of LoginModal which will open the modal in case status of API is 401

axios.interceptors.response.use(
  res => res,
  err => {
    if (err.response.status == 401) {
      router.push('/login')
      //call to component method instead instead of **router.push('/login')**
    }
  }
);

In vue templates we use references like this

this.$refs.loginModal.open()

but don't know how we can call component function from main.js

4
  • Can you please add some more code so we can help you solve it? Commented Feb 3, 2021 at 21:03
  • @maxshuty added axios interceptor code. this is how you can recreate 1.use axios for ajax calls 2.this whole code goes in main.js 3.In any vue component make an axios call to API which will return 401 status Commented Feb 4, 2021 at 0:55
  • I am successfully able to redirect user to login view when status is 401, but instead of redirect want to show the login modal Commented Feb 4, 2021 at 0:59
  • router.push('/login') 👈 you're navigating to some "login" route (and presumably component) here. Can you not open the modal from that component's mounted hook? Commented Feb 4, 2021 at 1:20

1 Answer 1

2

One way to accomplish what you are asking for, you can emit on your $root/vm, even though it in many cases is best practice to avoid doing so.

Anyway, in your main.js you can add this:

axios.interceptors.response.use(
  res => res,
  err => {
    if (err.response.status == 401) {
      vm.$emit('openLogin');
    }
  }
);

Then add your login modal to your App.vue instead of main.js, and in there listen on $root in mounted like so:

mounted() {
  this.$root.$on('openLogin', () => {
    this.$refs.loginModal.open()
  })
}
Sign up to request clarification or add additional context in comments.

3 Comments

In his post he already explained that his interceptor is in main.js, and in the first code piece of the post, he declares var vm = new Vue({ el: '#app', router, store }); So it should work as it is
Ah right, well spotted. I'll delete my comment
Thanks @ThomasBay for your help. Did not know that we can do an emit globally. Thanks for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.