ConsoleTVs / sswr

🔥 Svelte stale while revalidate (SWR) data fetching strategy
MIT License
234 stars 11 forks source link

`data` is `undefined` using reactive query #17

Open frederikhors opened 3 years ago

frederikhors commented 3 years ago

Using the below code it makes data === undefined. Why?

REPL: https://svelte.dev/repl/40782b4783244075b8c58cffbcf9acd4?version=3.42.1.

<script lang="ts">
  import { useSWR } from "sswr";

  let pagination = defaultPagination;

  $: ({ data, error } = useSWR(`players`, {
    fetcher: () => Promise.resolve(service.playerList({ pagination })),
  }));

  $: console.log("$error:", $error);
  $: console.log("$data:", $data); // $data === undefined as soon as I click Next page button

  function nextPage() {
    pagination = { ...pagination, page: $data.pageInfo.currentPage + 1 };
  }
</script>

<button on:click={nextPage}>Next page</button>

{#if $error} {$error.message} {:else if !$data} Loading... {:else}
<ul>
  {#each $data.players as player (player.id)}
  <li>
    <a href="/players/{player.id}">{player.id}</a>
  </li>
  {:else}
  <h1>No players</h1>
  {/each}
</ul>
{/if}
ConsoleTVs commented 3 years ago

Can I know more about what service.playerList does under the hood?

frederikhors commented 3 years ago

Can I know more about what service.playerList does under the hood?

In the REPL for this issue I used a simple fetch with the same issue: https://svelte.dev/repl/40782b4783244075b8c58cffbcf9acd4?version=3.42.1.

My service is similar.

frederikhors commented 3 years ago

THIS IS HUGE and prevent me from using sswr today.

ConsoleTVs commented 3 years ago

I'm going to explore this after work. Thanks for the report.

Terrahop commented 2 years ago

Having the same issue here with trying to get pagination to work.

Given the following code in a svelte component:

  /** Item position to start at */
  let offset = 0
  /** Number of items to get */
  let first = 10

  $: ({ data: pageData } = useSWR(() => 'pageItems', {
    fetcher: () => query('someItemList', { first, offset })
  }))

  $: console.log('page data', $pageData)

pageData is initially populated with data however when I update offset via a button press (offset += first), pageData becomes undefined and then no longer updates either on further changes to offset.

The same behaviour happens when not using a custom fetcher:

{...}
  $: ({ data: pageData } = useSWR(() => `api/someItemList?first=${first}&offset=${offset}`))
{...}
benbender commented 2 years ago

@Terrahop You are simply rerunning useSWR reactivly with different parameters. Therefor data is initialized as undefined at the beginning of the new request as per docs. See:

data: Writable<D | undefined>: Stores the data of the HTTP response after the fetcher has processed it or undefined in case the HTTP request hasn't finished or there was an error.

So imho this is expected behaviour.

The solution to this is either:

Terrahop commented 2 years ago

Ah got it thanks for clearing that up, I'll take a look at extending useSWR then.

akiarostami commented 2 years ago

I'm facing this issue as well, which is preventing me from using useSWR, unfortunately.