3.1.1
https://codesandbox.io/s/vue-template-i2d63
Use $router.push to change the "page". If you are using the same page, vue-router throw an Error.
Just nothing, or a warning.
An Error has been thrown.
<router-link> does not have the same behavior. There is no error even if you're pushing the current page.This is expected, it's part of the new promise api: before, if no callbacks were supplied to router.push, errors were only sent to the global router error handler. Now, because they return a promise, if the error is not caught, you will see a warning in the console. But the error was always there because trying to navigate to same location as the current one will fail
The behavior with router-link is consistent with how it was working before, no errors are emitted (except globally), it's catching the error by adding a _noop_ callback:
router.push('/location', () => {})
However, the correct solution if you don't care about errors is catching the error:
router.push('/location').catch(err => {})
The last version makes more sense as the Promise api is likely to become the default and the callback version to become deprecated
Hi @posva
In your types folder you can still find the push method as void
https://github.com/vuejs/vue-router/blob/dev/types/router.d.ts
is there a plan to fix this also ?
there are two versions of push and replace matching what actually happens
When trying to use the same I get this error, seems like typescript is looks only a the same definition because once I comment out the first
replace (location: RawLocation, onComplete?: Function, onAbort?: ErrorHandler): void;
it works.
before:

after:

Any idea why?
pushing a new URL (that is the same path as current page) but the search/hash makes the URL different, doesn't work anymore.
@shmaram I will give it a try and push a fix during the day, thanks for letting me know!
It's fixed now, I will publish a version during the day
@posva Why does it throw a NavigationDuplicated error when updating params, though? For instance, the router page might be named "User" and have params: { id: userId }. If you call this.$router.push({ name: 'User', params: { id: selectedUserId }}) to change the user being rendered for the current page, should that really count as a NavigationDuplicated error? This is the way it is recommended to change the data for a page, so it seems odd that getting an error is expected behavior.
the navigation failure should only happen if the final location is the same as the current one. If it happens with different params, it's a bug so please open a new issue with a boiled down repro
@posva Why does it throw a NavigationDuplicated error when updating params, though? For instance, the router page might be named "User" and have
params: { id: userId }. If you callthis.$router.push({ name: 'User', params: { id: selectedUserId }})to change the user being rendered for the current page, should that really count as a NavigationDuplicated error? This is the way it is recommended to change the data for a page, so it seems odd that getting an error is expected behavior.
I can confirm this behavior using this.$router.replace(). Just replacing the query params will cause the NavigationDuplicated error.
E.g., replacing #/search?term=lorem&sort=relevance with #/search?term=lorem&sort=alphabetical via
this.$router.replace({
path: '/search',
query: {
term: 'lorem',
sort: 'alphabetical'
}
})
will cause the NavigationDuplicated error if not catching via
this.$router.replace({
path: '/search',
query: {
term: 'lorem',
sort: 'alphabetical'
}
}).catch(err => {})
It will correctly update the current URL regardless of catching the error or not though.
Is this.$router.replace() not intended to be used for this? I didn't see any other function in the docs for just replacing the query params.
Is there a shorter way the prevent the console warning than router.push('/location').catch(err => {})?
Is it possible to decorate the push method to handle errors with a noop function?
@posva and what about redirecting inside a route guard?
next({ replace: true, name: 'home' }).catch(err => {})
Is this even possible? Because I'm getting this error caused by a route guard :(
@Aferz the catch must be attached to the push/replace methods
@posva Why does it throw a NavigationDuplicated error when updating params, though? For instance, the router page might be named "User" and have
params: { id: userId }. If you callthis.$router.push({ name: 'User', params: { id: selectedUserId }})to change the user being rendered for the current page, should that really count as a NavigationDuplicated error? This is the way it is recommended to change the data for a page, so it seems odd that getting an error is expected behavior.I can confirm this behavior using
this.$router.replace(). Just replacing the query params will cause theNavigationDuplicatederror.E.g., replacing
#/search?term=lorem&sort=relevancewith#/search?term=lorem&sort=alphabeticalviathis.$router.replace({ path: '/search', query: { term: 'lorem', sort: 'alphabetical' } })will cause the
NavigationDuplicatederror if not catching viathis.$router.replace({ path: '/search', query: { term: 'lorem', sort: 'alphabetical' } }).catch(err => {})It will correctly update the current URL regardless of catching the error or not though.
Is
this.$router.replace()not intended to be used for this? I didn't see any other function in the docs for just replacing the query params.
Is this fixed?
AFAIK the problem didn't appear when I tried. As with any other bug, a boiled reproduction is required. So please open a new issue with it if you can reproduce it. One possibility for the error to happen is to have another push somewhere else or next being called with the same location as the current one. I gave more details about it at https://github.com/vuejs/vue-router/issues/2881#issuecomment-520554378
Locking this one to redirect to that issue
Most helpful comment
I can confirm this behavior using
this.$router.replace(). Just replacing the query params will cause theNavigationDuplicatederror.E.g., replacing
#/search?term=lorem&sort=relevancewith#/search?term=lorem&sort=alphabeticalviawill cause the
NavigationDuplicatederror if not catching viaIt will correctly update the current URL regardless of catching the error or not though.
Is
this.$router.replace()not intended to be used for this? I didn't see any other function in the docs for just replacing the query params.