How to redo {#await ...} in Svelte?
Asked Answered
G

2

13

I want this to be fully client side rendering.. So, I don't want to refresh the page just to redo the promise..

Here's the code that I made..

{#await myFetchMethod("/api/v1/me")}
    <Loading />
{:then loggedIn}
    {#if loggedIn}
        <Link class="mb-0 h3" to="/profile">Profile</Link>
        <Link class="mb-0 h3" to="/logout">Logout</Link>
    {:else}
        <Link class="mb-0 h3" to="/login">Login</Link>
        <Link class="mb-0 h3" to="/register">Register</Link>
    {/if}
{:catch error}
    <p>Can't connect to the server!</p>
    <button on:click={whatShouldIDoHere}>Refresh</button>
{/await}

I want the refresh button to just redo the myFetchMethod("/api/v1/me") promise and get the result as intended.

Garton answered 17/7, 2019 at 4:7 Comment(0)
A
11

Instead of having the promise hardcoded to your API request, you could store it into a variable, add a function that refreshes the variable (i.e. fires the query again) and bind that function to the button's click event.

Something like this:

<script>
  let doLoginCheck = checkIfLoggedIn()

  function tryAgain() {
    doLoginCheck = checkIfLoggedIn()
  }

  function checkIfLoggedIn() {
    return fetch('/api/v1/me')
      .then(res => {
        if (!res.ok) {
          throw new Error('Cannot connect to server!');
        }
        return res.json();
      });
  }
</script>

{#await doLoginCheck}
  <Loading />
{:then loggedIn}
  {#if loggedIn}
    <Link class="mb-0 h3" to="/profile">Profile</Link>
    <Link class="mb-0 h3" to="/logout">Logout</Link>
  {:else}
    <Link class="mb-0 h3" to="/login">Login</Link>
    <Link class="mb-0 h3" to="/register">Register</Link>
  {/if}
{:catch error}
  <p>{error.message}</p>
  <button on:click={tryAgain}>Refresh</button>
{/await}
Allina answered 17/7, 2019 at 9:16 Comment(0)
L
4

Pass a parameter to your function that triggers a re-run on change.

{#await myFetchMethod("/api/v1/me", triggerParameter)}
...
{:then result}
...
{:catch error}
...
{/await}

The parameter does not necessarily to be used inside the async function. But when the value of the parameter changes, the function is run again. (When input changes, a new output is to expected).

To let it be triggered by a refresh button you can do:

<script>
  let trig = false;
</script>

{#await myFetchMethod("/api/v1/me", trig)}
    <Loading />
{:then loggedIn}
   ...
{:else}
   ...
{:catch error}

    <p>Can't connect to the server!</p>
    <button on:click={() => trig = !trig}>Refresh</button>
{/await}
Lowery answered 8/11, 2023 at 7:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.