mefechoel / svelte-navigator

Simple, accessible routing for Svelte
Other
502 stars 39 forks source link

beforeNavigate & afterNavigate hooks on Router #23

Closed KieranP closed 3 years ago

KieranP commented 3 years ago

I have a Svelte app where I can set errors into a store, and they will show up on the page. However, the errors persist after changing the page. It would be handy to have navigate hooks to clear the errors before the page navigates (either via Link click or navigate api). The ability to perform some actions after navigate could also be potentially useful, e.g. scrolling to a specific part of the page if needed.

Suggested improvement:

<Router hook:beforeNavigate={clearErrors} hook:afterNavigate={scrollPage}>
  ...
</Router>

It could also be used for things like stopping navigate if a form is unsaved. If a beforeNavigate hook returns false, then the navigation should not proceed.

quantuminformation commented 3 years ago

Don't like the extra complexity, too much like ember

mefechoel commented 3 years ago

Hey @KieranP! I don't want to extend the api too much, I'm with @quantuminformation there. But you can achive similar things with svelte-navigators api today.

If I understand your use case correctly you want to do something when the active route changes. In most cases that just means that the location changes. You coul build a component that accesses the routers location and resets your error state on a location change like so:

<!-- ErrorReste.svelte -->
<script>
  import { useLocation } from "svelte-navigator";
  import { errors } from "./stores";

  const location = useLocation();

  // location will always br truthy, but by putting it
  // in the condition svelte will re-run this block
  // everytime location changes
  $: if (location) {
    errors.reset(); // or whatever your interface looks like
  }
</script>

<slot />

You could also store the previous location so you can check if the pathname has changed if you need such details. Then you can put the component in your main router:

<!-- App.svelte -->

<Router>
  <ErrorReset>
    ...
  </ErrorReset>
</Router>
mefechoel commented 3 years ago

Regarding blocking navigation. I intend to implement that in v4 with an api similar to react-router's. It might not make it into 4.0 though... But if you need that functionality checkout #7 where we discussed a similar problem and solved it using a custom link component.

KieranP commented 3 years ago

@mefechoel Thank you for your example code. It was most helpful. I have been able to implement what I needed using this approach.