0

I have an annoying situation where I need to hook into every route change to check something. If condition X is true, I need to redirect to the homepage by showing a notice only on that single pageview. So I have the following:

router.beforeEach(() => {
  if (...) {
    store.showIneligibleBanner();
    return { path: '/' };
  }
  // in all other cases hide the banner
  store.hideIneligibleBanner();
  return true;
});

The problem is when I return { path: '/' } this triggers the beforeEach a second time and the conditional no longer applies. I know I could create more variables to keep track but I wanted a cleaner approach.

I am really just trying to show a banner a single time on that return redirect.

Tallboy
  • 12,847
  • 13
  • 82
  • 173

2 Answers2

0

That method takes a to (and from) parameters, which are the . So you can check if to.path === '/'.

danh
  • 62,181
  • 10
  • 95
  • 136
  • unfortunately this can apply on any route, and there are many redirects to home beside that. I was hoping there would be some way to trigger a guard only a single time, it seems theres really just no good way after researching for quite ahwile. – Tallboy Jul 01 '22 at 21:43
0

In store's state, store two vars: hasBannerBeenShown and isBannerVisible

router:

// ...
router.beforeEach((to, from, next) => {
  if (!store.hasBannerBeenShown && anyOtherFancyCondition) {
    store.hasBannerBeenShown = true;
    store.isBannerVisible = true;
    return { path: '/' };
  } 
  store.isBannerVisible && (store.isBannerVisible = false);
  next()
});

Note: The syntax above is based on the assumption you're using pinia. If you're using vuex, the syntax changes a bit (you'll need to commit mutations rather than assign to state), but the logic stays the same.

tao
  • 82,996
  • 16
  • 114
  • 150
  • yeah i thought of this, it's so much extra noise but i was hoping there was a more elegant way. ill just mark it as the answer as this seems to be (begrudgingly) how i need to do it – Tallboy Jul 02 '22 at 01:28
  • The only way to do an action only once per instance is to save the fact that it was done. Without saving, the system has no way of knowing whether the action was performed. It has nothing to do with elegance or style, it's just logic. Actually, some people would argue solid logic *does* have a particular elegance. The type of elegance well-made things have, even when they go out of fashion. – tao Jul 02 '22 at 11:19
  • I would not agree with you there. If you had asked me if a certain route hook triggers a second time if you are RETURNING the next route in the route hook, it makes no sense to me why it should trigger again. I would compare it to MVC if you are rendering the same controller action, if you return the response of another action it wouldn't call the entire action again. If you wanted to do that then you would actually redirect vs return. In this sense, i would expect returning wouldnt trigger it again, and if you wanted to do that you would push the route directly to vue-router like normal. – Tallboy Jul 03 '22 at 14:45
  • Making it so that you can't intercept a SINGLE route change with a single piece of logic isn't elegant. – Tallboy Jul 03 '22 at 14:46