vue-router's beforeEach guard exhibiting weird behaviour occasionally

Refresh

April 2019

Views

252 time

1

I've got the following code:

const routes = [
    { path: '/', component: FooView },
    { path: '/bar', component: BarView } 
];

const router = new VueRouter({
    routes
});

router.beforeEach(function(to, from, next) {
    if (to.path === '/bar') {
        next('/');    
    }

    next();
});

If I've omitted too much and you need to see other pieces of code related to the router let me know so I can fill it in.

If I open up a new tab and navigate to '/#/bar' I'm successfully redirected to '/#'. However, if I then go into the address bar and manually add '/#/bar' and hit enter I am not redirected. If I then hit enter in the address bar again I am redirected.

I've stepped through the code in the console and I see that it is calling next('/') and I see where it calls push('/') inside of next('/') but it doesn't take affect until I've hit enter in the address bar a second time.

I've tried using router.replace('/') but the behaviour is the same. I've tried using beforeEnter on the individual route but the behaviour is also the same.

Two links I've found where similar behaviour is discussed are: https://github.com/vuejs/vue-router/issues/748 and https://forum.vuejs.org/t/router-beforeeach-if-manually-input-adress-in-browser-it-does-not-work/12461/2 but neither helped me.

Is someone able to explain this? Is there a disconnect between what I'm trying to do and what functionality vue-router provides? If this behaviour isn't expected can someone propose a work around?

1 answers

0

Without getting too excited (a lot of testing left to do) it appears as though I've managed to fix my issue.

Instead of:

router.beforeEach(function(to, from, next) {
    if (to.path === '/bar') {
        next('/');    
    }

    next();
});

I changed the code to the following:

router.beforeEach(function(to, from, next) {
    if (to.path === '/bar') {
        next('/');

        return;
    }

    next();
});

Note the added return; in the if statement.

I still have questions about the behaviour. In particular I need too investigate deeper why sometimes it would hit the route when the only difference is whether it is the first or second time I entered the URL into the address bar. I'm sure diving deeper into next will answer my question.

Anyway, adding the return; turned this into a non blocker.