Search code examples
javascriptvue.jsvuejs2vue-router

TypeError: Cannot read properties of undefined (reading '$router') vuejs


So I'm trying to redirect user to diffrent route if api call returns status 422. but I'm getting an error

TypeError: Cannot read properties of undefined (reading '$router')

my routes.js:

{
        path: '/dashboard',
        component: Dashboard,
        name: 'Dashboard',
        beforeEnter: (to, form, next) =>{
            axios.get('/api/authenticated')
                .then(()=>{
                    next();
                }).catch(()=>{
                    return next({ name: 'Login'})
            })
        },
        children: [
            {
                path: 'documentCollections',
                component: DocumentCollection,
                name: 'DocumentCollections'
            },
            {
                path: 'document',
                component: Document,
                name: 'Document'
            },
            {
                path: 'createDocument',
                component: CreateDocument,
                name: 'CreateDocument'
            },
            {
                path: 'suppliers',
                component: Suppliers,
                name: 'Suppliers'
            },
            {
                path: 'settings',
                component: Settings,
                name: 'Settings'
            },
        ]
}

I also have login/register components and when I use

this.$router.push({ name: "DocumentCollections"});

It redirects user without any error. The problem is when I am in children component of dashboard component.

in documentCollections component i have a method:

    loadCollections(){
        axios.get('/api/documentCollections')
            .then((response) => {
                this.Collections = response.data.data
                this.disableButtons(response.data.data);
            })
            .catch(function (error){
                if(error.response.status === 422){
                    //here is where the error happens
                    this.$router.push({ name: "Settings"});
                }
            });
    },

That loads collections but if user has some data set null api return status 422. and I want him to be redirected to Settings component. (both documentCollection and Settings are child components of Dashboard)

why doesn't this.$router.push work here but works in login/register component?


Solution

  • Calling this inside a callback function creates a new binding to the this object instead of the Vue object in a regular function expression.

    You can use the arrow syntax to define the function, so this won't be overwritten.

    .catch((error) => {
        if(error.response.status === 422){
            this.$router.push({name: "Settings"});
        }
    })
    

    More information

    Another option

    Define another instance of this before the axios call and use it after you received the response.

    let self = this
    ...
    self.$router.push({name: "Settings"})
    

    With your code

    loadCollections(){
        let self = this;
        axios.get('/api/documentCollections')
            .then((response) => {
                this.Collections = response.data.data
                this.disableButtons(response.data.data);
            })
            .catch(function (error){
                if(error.response.status === 422){
                    self.$router.push({name: "Settings"});
                }
            });
    },