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

Nested routes click to parent problem #56

Closed
rottmann opened this issue Nov 7, 2019 · 3 comments
Closed

Nested routes click to parent problem #56

rottmann opened this issue Nov 7, 2019 · 3 comments

Comments

@rottmann
Copy link

rottmann commented Nov 7, 2019

Example:

npx degit sveltejs/template nested-routes
cd nested-routes
npm install svelte-spa-router
npm install
npm run dev

App.svelte

<script>
  import Router from 'svelte-spa-router'
  import CallView from './CallView.svelte'

  const routes = {
    '/call/*': CallView
  }
</script>
<Router {routes}></Router>

CallView.svelte

<script>
  import Router, { push } from 'svelte-spa-router'
  import CallEditView from './CallEditView.svelte'

  const routes = {
    '/call/edit/:id': CallEditView
  }

  // this is only called one time, when the page load, but not wenn you push the button
  // (onMount / async stuff fake)
  setTimeout( () => {
    push('/call/edit/1')
  }, 1000)
</script>

<button on:click={() => push('/call/') }>Go to /call/</button><br>

<Router {routes}></Router>

CallEditView.svelte

<script>
  export let params = {}
</script>

Edit {params.id}

Open http://localhost:5000/#/call/
after 1 second CallView pushes to nested view /call/edit/1
click the button,
no nested view is visible, cause setTimeout/onMount is only called once.

@ItalyPaleAle
Copy link
Owner

Hi @rottmann sorry for the delay in responding.

This is actually not an issue in the router itself, but it's how Svelte works. The "problem" is that your code never causes the CallView component to be un-mounted (removed from the DOM), so Svelte doesn't re-mount it. You can confirm this behavior by changing the code of CallView.svelte to:

<script>
  import Router, { push } from 'svelte-spa-router'
  import CallEditView from './CallEditView.svelte'
  import { onMount } from 'svelte'

  const routes = {
    '/call/edit/:id': CallEditView
  }

  onMount(async () => {
	console.log('mounted')
  })

  // this is only called one time, when the page load, but not wenn you push the button
  // (onMount / async stuff fake)
  setTimeout( () => {
    push('/call/edit/1')
  }, 1000)
</script>

<button on:click={() => push('/call/') }>Go to /call/</button><br>

<Router {routes}></Router>

In the console, you'll see that "mounted" appears only once. This is by design.

There's a simple workaround, however, which is to listen on the $location store. Here's an example with an updated CallView.svelte:

<script>
  import Router, {push, location} from 'svelte-spa-router'
  import CallEditView from './CallEditView.svelte'
  import {onDestroy} from 'svelte'

  const routes = {
    '/call/edit/:id': CallEditView
  }

  const unsubscribe = location.subscribe((val) => {
    setTimeout( () => {
        console.log('pushing')
        push('/call/edit/1')
    }, 1000)
  })

  onDestroy(async () => {
	unsubscribe()
  })
</script>

<button on:click={() => push('/call/') }>Go to /call/</button><br>

<Router {routes}></Router>

@rottmann
Copy link
Author

Thank you! Other solution could be to react on location change with$: $location, will try both.

@ItalyPaleAle
Copy link
Owner

The two things are equivalent. The $ syntax behind the scene manages the subscription/un-subscription automatically, as per the svelte documentation!

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

2 participants