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

Support for cancelling navigation? #33

Open
germanftorres opened this issue Jun 13, 2020 · 2 comments
Open

Support for cancelling navigation? #33

germanftorres opened this issue Jun 13, 2020 · 2 comments

Comments

@germanftorres
Copy link

germanftorres commented Jun 13, 2020

Hi,
Is it possible to cancel navigation in navaid? In an editor scenario I would like to setup a dirty flag so that if the user wants to navigate off the page while the editor has changes, to prompt the user and give him the chance to cancel navigation.

In the svelte-demo repo I have seen a good example of route guards for the protected/admin area scenario. Following that sample code, I could conditionally prompt the user based on a dirty flag and do nothing at all if he or she chooses to cancel. But from navaids point of view, the navigation would have already happened and the history would reflect the new url.

I thinks a beforeNavigation hook would be a great addition to the the library.

Is it possible to solve this scenario in navaids current incarnation?

Thanks!!

const router = (
  Navaid('/')
  // support for cancelling navigation??
  .beforeNavigation((newPath, oldPath) => {
    if($dirtyFlag) {
      // prompt user  
      // return false to cancel navigation      
      return false;
    }
    return true;
  })
  .on('/', () => run(import('../routes/Home.svelte')))
  .on('/about', () => run(import('../routes/About.svelte')))
  .on('/login', () => run(import('../routes/Login.svelte')))
  .on('/private', () => onAdmin(import('../routes/Private.svelte')))
  .on('/forbidden', () => run(import('../routes/Forbidden.svelte')))
  .on('/blog', () => run(import('../routes/Blog.svelte')))
  .on('/blog/:postid', obj => run(import('../routes/Article.svelte'), obj))
  );
function onAdmin(thunk, obj) {
  if ($isAdmin) return run(thunk, obj);
  if ($isUser) return router.route('/forbidden', true);
  router.route('/login', true);
}
@aldomendez
Copy link

I also vote for this. As I am trying a series of hacks and no one works... 😢

@AlexGalays
Copy link

The first router that did this was Ember's and it was bugged like crazy. It's in fact a very difficult problem, perhaps impossible to solve. When you click on the back button and select some very old history entry in the dropdown, a script can't really do much but accept that after the fact. Also the popstate event is not cancellable. Sometimes the history entries cross different websites too; so unless I'm wrong and forgetting some APIs, you can't cancel navigation, nor can you simulate it for end users by reverting the change because you can't fiddle with history in such a fine grained fashion (i.e, you can only push new entries at the top of the stack, not insert some back in the middle)

So, perhaps try to do that before routing occurs at all and handle it in an async fashion for when it already happened (popstate) via some bubble UI, etc.

PS: These "are you sure you want to navigate away" popups are very annoying anyway; a way better UX is to just remember the last draft :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants