2

I am calling an API via a formulat with Svelte and would like to output the results in a loop:


    <script> 
      let varHaystack,
        varNeedle,
        result,
        hasData,
        json = null;
      varHaystack = "lang";
      varNeedle = "php";
      async function doSearch() {
        const res = await fetch("https://dev.domain.de/test/api.php?search", {
          method: "POST",
          body: JSON.stringify({
            search: {
              needle: varNeedle,
              haystack: varHaystack,
            },
          }),
        });

        json = await res.json();
        result = JSON.stringify(json);
        hasData = true;
        console.log(json);
      }
    </script>

    <input placeholder="Needle" bind:value={varNeedle} />
    <input placeholder="Haystack" bind:value={varHaystack} />
    <button type="button" on:click|preventDefault={doSearch}> Post it. </button>

    <p>Result:</p>
    <pre>
      {result}
    </pre>

    <!-- first attempt -->
    {#if hasData}
      <div>
        {#await json}
          <p>Loading...</p>
        {:then json}
          {#each json as user}
            <p>Name is {user.lang}</p>
          {/each}
        {:catch error}
          <p style="color: red">{error.message}</p>
        {/await}
      </div>
    {/if}

    <!-- second attempt -->
    {#if hasData}
      {#each json as d}
        <tr>
          <td>{d.id}</td>
        </tr>
      {:else}
        <p>Loading...</p>
      {/each}
    {/if}

The JSON object is correctly timed in the console and in the pre tag, just not in either of the two loop attempts.

It always gives the error: Uncaught (in promise) Error: {#each} only iterates over array-like objects.

The JSON output as a string looks like this:
{ "8": { "date": "1999-11-13 01:56:50", "lang": "PHP" }, "12": { "date": "1999-11-13 01:56:50", "lang": "PHP" }

1
  • Looks like a "normal" object. A normal object is not array-like. If you want to iterate over the object's property values you can use Object.values(json). Commented Nov 29, 2021 at 9:48

1 Answer 1

2

Thanks to the comment from @Felix Kling, this works:

{#if hasData}
  {#each Object.values(json) as d}
    <tr>
      <td>{d._id}</td>
      <td>{d.desc}</td>
    </tr>
  {/each}
{:else}
  <p>Loading...</p>
{/if}
Sign up to request clarification or add additional context in comments.

1 Comment

If you found a solution to your question, you might mark it as answered

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.