How to bind a svelte component's state to the query string in Sapper
Asked Answered
A

1

8

My sapper app revolves around a table component. This table component has state (offset, limit, sort, filters, etc) that I would like to represent in the query string of the URL.

The table works fine currently by directly updating its state:

<button on:click="{() => offset += limit}" disabled="{offset + rows.length >= count}">»</button>

I see that there is the page read-only store which can give me access to the current value of the query string. I imagine I can use something like URLSearchParams to generate links with the relevant value updated.

Is there a better way of handling this (some way of directly binding variables to the query string)? If not, what would be the best way to generate the links with the updated query strings?

EDIT:

My current solution is the following function:

const getLink = queryStringDiff =>  {
  const query = $page.query;
  const path = $page.path;
  const str = Object.entries({...query, ...queryStringDiff}).reduce(
    (acc, cur) => `${acc}&${cur[0]}=${cur[1]}`, ''
  ).replace('&', '?');
  return `${path}${str}`;
}

Which I reference in an a tag replacing the above button with:

href="{getLink({'offset': (offset - limit)})}"

It works, but I feel like there should be a better way

Arhna answered 23/6, 2019 at 14:41 Comment(0)
V
20

You can access query string state from the page store:

<script>
  import { stores } from '@sapper/app';
  const { page } = stores();

  $: start = $page.query.p * $page.query.itemsPerPage;
  $: end = start + $page.query.itemsPerPage;

  $: slice = myData.slice(start, end); // plus filtering, sorting etc
</script>

<table>
  <thead>...</thead>
  <tbody>
    {#each slice as row}
      <tr>...</tr>
    {/each}
  </tbody>
</table>

<a href="my-table?p={$page.query.p + 1}">next</a>

If you need to navigate programmatically, you can use goto:

<script>
  import { stores, goto } from '@sapper/app';

  // ...

  const next = () => {
    goto(`my-table?p=${$page.query.p + 1}`);
  };
</script>
Vase answered 24/6, 2019 at 12:15 Comment(2)
Wow, an answer from the creator himself! This is definitely the idea, but it gets more complicated when you have an arbitrary number of things in the query string - I updated the question with the method I needed to writeArhna
what is this next function?Globoid

© 2022 - 2024 — McMap. All rights reserved.