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

afterResolve global navigation hook #2079

Closed
cironunes opened this issue Feb 28, 2018 · 16 comments · Fixed by #2292
Closed

afterResolve global navigation hook #2079

cironunes opened this issue Feb 28, 2018 · 16 comments · Fixed by #2292
Labels
fixed on 4.x This issue has been already fixed on the v4 but exists in v3 has PR improvement

Comments

@cironunes
Copy link

What problem does this feature solve?

As opposed to beforeResolve, afterResolve would wait until the navigation is done and trigger the registered callbacks.

The main reason for that is to be able to track events in the right moment, with the proper url in place, globally.

What does the proposed API look like?

routerInstance.afterResolve(cb);
function cb(from, to, next) {...}

I'd love to submit a PR if that's something you'd like to have.

@posva
Copy link
Member

posva commented Feb 28, 2018

What do you need to do there that you cannot do in afterEach?

@cironunes
Copy link
Author

Run callback functions after the URL changes

@posva
Copy link
Member

posva commented Feb 28, 2018

but you already have the url in afterEach in to.fullPath

@cironunes
Copy link
Author

cironunes commented Feb 28, 2018

Yes. Issue is that the URL in the browser doesn't match and we have automated scripts that rely on that.

I created a repository reproducing what I mean:
Repository: https://github.com/cironunes/vue-router-afterEach
Demo: https://cironunes.github.io/vue-router-afterEach/#/

Please click the route-links and verify the console.

This would be solved if we could create a global navigation guard to run before (or after) the postEnterCbs

@cironunes cironunes changed the title afterResolve global navigation guard afterResolve global navigation hook Mar 1, 2018
@posva
Copy link
Member

posva commented Mar 1, 2018

In that case, would you still use afterEach? Maybe afterEach should simply be called once the url in the browser is updated

@cironunes
Copy link
Author

cironunes commented Mar 1, 2018

@posva yep. Also thought about it. My concern was to introduce a breaking change so I though I just add a new hook instead. Would you be happy to accept my PR if I change it to make afterEach be called once the URL is updated?

@cironunes
Copy link
Author

Any news? I'm happy to update my PR.

posva added a commit that referenced this issue Jul 10, 2018
Closes #2079

This helps integrating with external scripts and makes more sense as the
navigation is finished.  However, onComplete callback passed to
`router.push` is now called before `afterEach` hooks. This shouldn't be
a problem as there's no guarantee provided anywhere in the docs about
this
@posva
Copy link
Member

posva commented Jul 10, 2018

hello, I think it will make more sense if afterEach hooks are called once url is updated.
I don't see what usecase would require afterEach to be executed before. Do you (or any other person interested in this) see any inconvenience with #2292 ? The only change is that onComplete (router.push) will get executed before afterEach hooks, but this shouldn't be a problem. If it is, please tell me how it would be 🙂

@chrisnicola
Copy link

@posva I agree with this, I just noticed while hooking up some analytics scripts that the URL is not updated when afterEach is called. Using setTimeout(fn, 0) works as a bit of a hack for now, but is a less than ideal solution. I was kind of surprised that afterEach was not called after the components had been fully loaded.

Another reason for that is that it is common to also often updating the HTML title value using the main route component. Again analytics/tracking scripts often rely on reading this metadata.

Completely agree with having afterEach wait until the route is full loaded and the component is rendered.

posva added a commit that referenced this issue May 9, 2019
Closes #2079

This helps integrating with external scripts and makes more sense as the
navigation is finished.  However, onComplete callback passed to
`router.push` is now called before `afterEach` hooks. This shouldn't be
a problem as there's no guarantee provided anywhere in the docs about
this
@maroon1
Copy link

maroon1 commented Oct 15, 2019

@posva I think that is useful there is a way to track the lifecycle of the router. for now, it seems that we can not globally handle navigation failed or canceled.

@posva
Copy link
Member

posva commented Oct 15, 2019

you have router.onError for global errors

@maroon1
Copy link

maroon1 commented Oct 17, 2019

How do we determine the end of navigation for navigation canceled by invoking next(false)?

@maroon1
Copy link

maroon1 commented Oct 17, 2019

There is a series of event in angular router, so we can listen to some interested event to do something.

@chrisnicola
Copy link

@maroon1 if you want to handle something after aborting I think @posva is correct, you should pass an error like next(Error) and router.onError, will be called.

I could potentially see a use case for supporting an onAbort that doesn't require an error, but I'd be concerned about being able to determine the cause given that only false is passed. In my mind this is the benefit of passing the Error object.

Do you have a use case where you want to do something globally after aborting that is not an error?

@maroon1
Copy link

maroon1 commented Oct 18, 2019

@chrisnicola I want to implement a feature that show a indicator(a top progress bar) when navigating. I put all data request(or other async action) in beforeRouteEnter or beforeEnter hook and show the progress bar before navigation , so i need to know what time to hide the progress bar.It's obvious that the progress could be hidden after end of navigation either success or failure. In this case we don't care about the result of navigation, just know it's end and do some thing finally.

@chrisnicola
Copy link

Is there a reason afterEach can't be used for this?

Do I understand correctly that you are looking for a global hook that is run after step 12 in this list that includes a reference to the component instance?

https://router.vuejs.org/guide/advanced/navigation-guards.html#the-full-navigation-resolution-flow

@posva is there any reason this shouldn't be supported with a global hook instead of requiring a callback passed to next at the component level?

@posva posva added the fixed on 4.x This issue has been already fixed on the v4 but exists in v3 label Mar 18, 2020
andresdameson added a commit to WhoKnowsAgency/fucernet that referenced this issue May 25, 2020
En Firefox al menos se anunciaba el título de la página anterior. El
hook `afterEach` de vue-router se ejecuta ANTES de que termine de
armarse el componente de la página y vue-announcer lee el título ANTES
de que se actualice.

En vue-announcer lo tienen en cuenta pero parece que en Firefox no
funciona su fix:
vue-a11y/vue-announcer@50c3cae#diff-1fdf421c05c1140f6d71444ea2b27638

En vue-router tienen previsto hacer cambios en el hook para evitar este
tipo de problemas:
vuejs/vue-router#2079
posva added a commit that referenced this issue May 26, 2020
Closes #2079

This helps integrating with external scripts and makes more sense as the
navigation is finished.  However, onComplete callback passed to
`router.push` is now called before `afterEach` hooks. This shouldn't be
a problem as there's no guarantee provided anywhere in the docs about
this
andresdameson added a commit to WhoKnowsAgency/fucernet that referenced this issue May 28, 2020
En Firefox al menos se anunciaba el título de la página anterior. El
hook `afterEach` de vue-router se ejecuta ANTES de que termine de
armarse el componente de la página y vue-announcer lee el título ANTES
de que se actualice.

En vue-announcer lo tienen en cuenta pero parece que en Firefox no
funciona su fix:
vue-a11y/vue-announcer@50c3cae#diff-1fdf421c05c1140f6d71444ea2b27638

En vue-router tienen previsto hacer cambios en el hook para evitar este
tipo de problemas:
vuejs/vue-router#2079
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed on 4.x This issue has been already fixed on the v4 but exists in v3 has PR improvement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants