kalana93
kalana93

Reputation: 71

Vue-router push undefined

I used Quasar framework to design my UI. When I use a function to logout and push to another route using vue-router I got the following error:

TypeError: Cannot read property 'push' of undefined

I use a vuex action method to logout and replace:

export const handleAuthStateChanged = ({ commit }, payload) => {
  firebaseAuth.onAuthStateChanged(function(user) {
    if (user) {
      // user is logged in
      let userId = firebaseAuth.currentUser.uid;
      firebaseDB.ref("users/" + userId).once("value", function(snapshot) {
        let userDetails = snapshot.val();
        commit("USER_DETAILS", {
          name: userDetails.name,
          email: userDetails.email,
          online: userDetails.online,
          type: userDetails.type,
          userId: userId
        });
      });
      this.$router.push('');
    } else {
      // user is logged out
      commit("USER_DETAILS", {});
      this.$router.replace('chat');
    }
  });
};

How can i fix this?

Upvotes: 1

Views: 7073

Answers (3)

kalana93
kalana93

Reputation: 71

Thank you all for try to fix my issue. i fixed it using without using arrow functions in vuex actions.

export const handleAuthStateChanged = function ({ commit }, payload) {
...

Upvotes: 0

Dan
Dan

Reputation: 63059

There are two issues:

  • The this context issue already covered by @MisterCurtis's answer

    Normal functions have their own this context while es6 arrow functions inherit it. Some reading about that.

  • this.$router only makes sense if this is a component instance. Vue inserts your router onto its instance prototype. But this code is a Vuex action, not an instance method.

To use vue-router in an external module, like Vuex, or any other module, you can import it:

import router from '@/router'

And then use

router.push

instead of this.$router.push

An alternative would be to manage the auth result in the login component and use this.$router there.

Upvotes: 2

MisterCurtis
MisterCurtis

Reputation: 191

Any new function will define its own this value. Inside your callback this is no longer pointing to the original Vue instance "this".

Try changing:

firebaseAuth.onAuthStateChanged(function(user) { ...

to an arrow function:

firebaseAuth.onAuthStateChanged((user) => { ...

this will then properly refer to the original Vue instance where $router is defined.

Upvotes: 1

Related Questions