简体   繁体   中英

Can't redirect after login?

Getting a TypeError: Cannot read property '$router' of undefined when trying to redirect after login. I have tried various methods on the router instance but it is undefined according to the console?

Login action (inside store):

login({ commit, dispatch }, { username, password }) {
    const querystring = require('querystring');

    this.$axios.$post('connect/token', querystring.stringify({
        client_id: process.env.CLIENT_ID,
        client_secret: process.env.CLIENT_SECRET,
        username,
        password,
        grant_type: 'password'
    }))
    .then(function (response) {
        dispatch('setToken', { 
            token: response.access_token, 
            expiresIn: response.expires_in 
        });

        this.$router.push({name: 'home' }); // this line is the issue
    })
    .catch(errors => {
      console.dir(errors);
    });
},

You just need to preserve this before calling it again inside .then(...) like:

login({ commit, dispatch }, { username, password }) {

    // Store `this` inside variable vm here
    const vm = this;
    const querystring = require('querystring');

    vm.$axios.$post('connect/token', querystring.stringify({
        client_id: process.env.CLIENT_ID,
        client_secret: process.env.CLIENT_SECRET,
        username,
        password,
        grant_type: 'password'
    }))
    .then(function (response) {
        dispatch('setToken', { 
            token: response.access_token, 
            expiresIn: response.expires_in 
        });

        // Use this for debugging purpose only
        console.log( vm.$router )

        // You can now access `$router` safely here now
        vm.$router.push({name: 'home' });
    })
    .catch(errors => console.dir(errors));
},

Your problem is that you use this inside an regular function, that means that this is binded to the function and not the vue instance, change it to an arrow function:

.then((response) => {
        dispatch('setToken', { 
            token: response.access_token, 
            expiresIn: response.expires_in 
        });

        this.$router.push({name: 'home' }); // this line is the issue
    })

Other solution is to .bind() it:

.then(function (response) {
        dispatch('setToken', { 
            token: response.access_token, 
            expiresIn: response.expires_in 
        });

        this.$router.push({name: 'home' }); // this line is the issue
    }.bind(this))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM