Element: [Bug Report] 'undefined' error after clicking el-menu-item in router mode

Created on 13 Feb 2018  ·  11Comments  ·  Source: ElemeFE/element

Element UI version

2.2.0

OS/Browsers version

Windows 10/Chrome 64

Vue version

2.5.13

Reproduction Link

https://github.com/aaronfulkerson/vue-test/blob/master/src/router/index.js#L27

Steps to reproduce

Create navigation guard for the routes being navigated to and enable router mode in el-menu then click el-menu item -> 'undefined' error in console

What is Expected?

No error.

What is actually happening?

Something goes wrong when next() is reached in a navigation guard, causing an "undefined" error in the console when using el-menu to navigate.
https://github.com/aaronfulkerson/vue-test/blob/master/src/router/index.js#L27

Most helpful comment

I found the reason: The implementation of beforeResolve guard has caused vue-router to trigger onAbort event.

In Element 2.2.0, Menu will console.error when a router update is aborted, as a remainder to the developer. The undefined is printed by this console.error. That's all the difference between 2.1.0 and 2.2.0 on this matter.

Main reason is that beforeResolve will call next twice, which makes vue-router think the router update is aborted (I'm not sure if this is intentional for vue-router, though). If you merge my pull request, you'll find that both 1 and 2 are printed each time you change the route. So the beforeResolve guard is practically calling next twice just like:

router.beforeResolve((to, from, next) => 
  next()
  next()
)

I'm sure if you guarantee that next is called only once for every route update, the undefined in console will go away.

All 11 comments

I tested in a new project with your gist and it works fine. Note that vue-router is required when router mode is enabled.

If you still cannot get your project to work, please minify it and push it to a GitHub repo so we can take a look.

The crazy part is that everything works just fine but I'm getting 'undefined' errors in the console.

Here's a repo: https://github.com/aaronfulkerson/vue-test

Please minify your repo. For now it is required to login.

I've never heard of minifying a repo before and there are a lot of results for "minify GitHub" and "minify repo". Can you point me in the right direction?

A reproduction repo should be as small as possible, as long as it can reproduce the bug.

For example, when I clone your repo and run yarn and npm run dev, I cannot go to the page where the bug lies because I'm required to login. Since there's no server code in the repo, it is impossible for me to login. As a result, I can't check the bug.

Please remove all login logics and other business logics that has nothing to do with this bug. After that, please tell me which page I should go.

Plus, your repo uses Element 2.1.0 instead of 2.2.0: https://github.com/aaronfulkerson/vue-test/blob/master/yarn.lock#L2078 . So this doesn't seem to be a regression of Element.

My mistake. For testing purposes I reverted to 2.1.0 before copying the code. The current version of the test repo should have the bug present and allow you to login. To login simply click login. Then try using the menu and pay attention to the console. I've tracked the bug down to the index file of the router in the navigation guard: https://github.com/aaronfulkerson/vue-test/blob/master/src/router/index.js#L27

If I revert to 2.1.0 there's no error but while using 2.2.0, the only way to get rid of the 'undefined' error is to remove the navigation guard.

I found the reason: The implementation of beforeResolve guard has caused vue-router to trigger onAbort event.

In Element 2.2.0, Menu will console.error when a router update is aborted, as a remainder to the developer. The undefined is printed by this console.error. That's all the difference between 2.1.0 and 2.2.0 on this matter.

Main reason is that beforeResolve will call next twice, which makes vue-router think the router update is aborted (I'm not sure if this is intentional for vue-router, though). If you merge my pull request, you'll find that both 1 and 2 are printed each time you change the route. So the beforeResolve guard is practically calling next twice just like:

router.beforeResolve((to, from, next) => 
  next()
  next()
)

I'm sure if you guarantee that next is called only once for every route update, the undefined in console will go away.

That makes perfect sense. I wouldn't have figured this out for a while.

There's another problem here and I'm not sure it can be resolved with changing my app's logic. vue-router will abort navigation if you attempt to browse to the same route. In other words, it will call abort() if you click on the same menu item twice causing Element to throw an error.

We'll remove the console.error in the next release.

Would it be better to leave console.error in case navigation aborts for another reason and just not push a new route if you're trying to navigate to the same page?

Was this page helpful?
0 / 5 - 0 ratings