Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catch cancelled navigations #2012

Open
posva opened this issue Jan 19, 2018 · 8 comments
Open

Catch cancelled navigations #2012

posva opened this issue Jan 19, 2018 · 8 comments
Labels
feature request fixed on 4.x This issue has been already fixed on the v4 but exists in v3

Comments

@posva
Copy link
Member

posva commented Jan 19, 2018

What problem does this feature solve?

This will allow users to hook on:

  • redirections to the current route (could be a different hook like onRedirect, also triggered by redirect option)
  • next(false) calls
  • navigation delayed and replaced by other navigations:
    • eg: users click when async component not finished loading

I'm a bit sceptical about use cases on why to hook on redirects, so I'll love to read if you have usecases

What does the proposed API look like?

router.onCancel((to, from, currentLocation) => {
  // from -> original route where the navigation was triggered
  // to -> where was it supposed to go
  // currentLocation -> location where we ended up (same as this.$route in components and router.currentRouter
})

can be triggered by

router.beforeEach((to, from, next) => {
  next(false) // cancel navigation explicitely
})

router.beforeEach((to, from, next) => {
  to.fullPath // /foo
  from.fullPath // /home
  // redirect to /home if we're on /foo
  // this will do nothing if we are already on /home
  if (to.fullPath === '/foo') next('/home')
  else next()
})
@ghost
Copy link

ghost commented Sep 10, 2018

@posva, here's a use case https://stackoverflow.com/questions/52241102/vue-router-callback-when-navigation-is-cancelled

@jgradzki
Copy link

@posva When we can expect this? Im just asking :)

@posva
Copy link
Member Author

posva commented May 21, 2019

It depends on how much time I can allocate to open source but this one needs more thinking because redirecting can happen in different situations and not all are considered the same (in navigation guard vs in route record). As I'm working on the next version of Vue Router I may find other suitable APIs.
I won't be able to work on this anytime soon unfortunately

@jgradzki
Copy link

Thank you very much for response :)

@posva
Copy link
Member Author

posva commented Mar 29, 2020

There is an RFC that solves this vuejs/rfcs#150

@posva posva added the fixed on 4.x This issue has been already fixed on the v4 but exists in v3 label May 26, 2020
@Tofandel
Copy link

Tofandel commented Nov 30, 2020

One related question, is it possible to force a router.push? As in force it not to be cancelled? I have some edge case where the user submits a form and this triggers a redirect I need to force this redirect to not be cancelled, because it can happen that while the redirect occurs, an other router.push is triggered at the exact same time in a completely unrelated code: I have a section observer pushing the current hash/id of the section to the router. So basically if you scroll while submitting you may not get redirected..

I'm thinking something like this.$router.push({name: 'foo', {force: true}); or on the other code

if (!this.$router.isPending) {
  this.$router.push({name: 'bar', {hash: 'baz'});
}

@posva It seems the pending property could do the trick in the base history, but it doesn't seem to be exposed through a public router api so right now I am able to do
this.$router.history.pending === null, but with no guarantee it will continue to work

@posva
Copy link
Member Author

posva commented Nov 30, 2020

@Tofandel A pendingLocation could indeed be exposed, it's worthy of an RFC to discuss if it should unset once a navigation is done, different solutions and problems that may arise. It can be implemented in user land with a combination of router.beforeEach, router.afterEach and router.onError

@lgarczyn
Copy link

lgarczyn commented Jul 2, 2021

@posva It actually cannot be implemented in user land easily, since onError is not called after next(false)

Such a 'loading' state would also not include beforeRouteLeave callbacks (though those are usually not async).

Currently the simplest way is to create a cancelRouting function that takes next and resets the loading marker, and forbid any use of next(false)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request fixed on 4.x This issue has been already fixed on the v4 but exists in v3
Projects
None yet
Development

No branches or pull requests

4 participants