Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 388
Philip C Avatar asked Jun 23 '19 14:06

Philip C


People also ask

How do I get URL parameters in svelte?

url. searchParams. get('xxx') to get a url query param.


1 Answers

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>
like image 115
Rich Harris Avatar answered Sep 30 '22 18:09

Rich Harris