API响应的`.json`数组在Svelte中为什么不可迭代?

huangapple go评论77阅读模式
英文:

Why is an API response.json array not iterable in Svelte?

问题

I've been working on a simple nutrition tracking app as a final project for CS50, using Svelte and Firebase to make it fully functional. I've run into a problem in the frontend, as I'm using API calls to retrieve nutrition information. The API returns a json array which I would use to present options to the user and log information as they select. However, when I try to iterate over this array to make an option for each, I receive an error stating that it is not an array-type object.

I decided to reproduce the code in REPL, and achieved good results. The below code logs the full 50 items as an array, as per the API's documentation.

import { onMount } from 'svelte';

let foodList;
async function loadList() {
    let list = await fetch('https://api.nal.usda.gov/fdc/v1/foods/list?dataType=Foundation&api_key=DEMO_KEY');
    let foodList = await list.json();
    console.log(foodList);
}

onMount(() => {
    loadList();
});

I receive this abbreviated output:

(50) [ {…} ,{…} ,{…} ,{…} ,{…} , … ]

However, when trying to iterate over this array, I receive the error:

{#each} only iterates over array-like objects.

using below code:

{#await loadList}
    <p>
        Loading...
    </p>
{:then foodList}
    {#each foodList as item}
        <p>
            {item.description}
        </p>
    {/each}
{:catch error}
    <p style="color: red">{error.message}</p>
{/await}

I would appreciate any help, as I feel like I'm missing something fundamental that might be obvious to some others.

英文:

I've been working on a simple nutrition tracking app as a final project for CS50, using Svelte and Firebase to make it fully functional. I've run into a problem in the frontend, as I'm using API calls to retrieve nutrition information. The API returns a json array which I would use to present options to the user and log information as they select. However, when I try to iterate over this array to make an option for each, I receive an error stating that it is not an array-type object.

I decided to reproduce the code in REPL, and achieved good results. The below code logs the full 50 items as an array, as per the API's documentation.

import { onMount } from &#39;svelte&#39;;
	
    let foodList;
    async function loadList() {
        let list = await fetch(&#39;https://api.nal.usda.gov/fdc/v1/foods/list?dataType=Foundation&amp;api_key=DEMO_KEY&#39;);
        let foodList = await list.json();
        console.log(foodList);
    }
		
    onMount(() =&gt; {
	loadList();
    });	

I receive this abbreviated output:

(50) [ {…} ,{…} ,{…} ,{…} ,{…} , … ]

However, when trying to iterate over this array, I receive the error:

{#each} only iterates over array-like objects.

using below code:

{#await loadList}
	&lt;p&gt;
		Loading...
&lt;/p&gt;
{:then foodList}
	{#each foodList as item}
		&lt;p&gt;
			{item.description}
	&lt;/p&gt;
	{/each}
{:catch error}
	&lt;p style=&quot;color: red&quot;&gt;{error.message}&lt;/p&gt;
{/await}

I would appreciate any help, as I feel like I'm missing something fundamental that might be obvious to some others.

答案1

得分: 0

Your #await is trying to check the function, not a promise.

Could you try this?

<script>
	async function loadFoodList() {
        const res = await fetch('https://api.nal.usda.gov/fdc/v1/foods/list?dataType=Foundation&api_key=DEMO_KEY');
        const foodList = await res.json();

        if (!res.ok) {
			throw new Error("Something's wrong");
		}

        return foodList;
    }
	
	const foodListPromise = loadFoodList();
</script>

{#await foodListPromise}
	<p>Loading...</p>
{:then foodList}
	{#each foodList as item}
        <p>{item.description}</p>
    {/each}
{:catch error}
	<p style="color: red">{error.message}</p>
{/await}

You can read more here: https://svelte.dev/tutorial/await-blocks

英文:

Your #await is trying to check the function, not a promise.

Could you try this?

&lt;script&gt;
	async function loadFoodList() {
        const res = await fetch(&#39;https://api.nal.usda.gov/fdc/v1/foods/list?dataType=Foundation&amp;api_key=DEMO_KEY&#39;);
        const foodList = await res.json();

        if (!res.ok) {
			throw new Error(&quot;Something&#39;s wrong&quot;);
		}

        return foodList;
    }
	
	const foodListPromise = loadFoodList();
&lt;/script&gt;

{#await foodListPromise}
	&lt;p&gt;Loading...&lt;/p&gt;
{:then foodList}
	{#each foodList as item}
        &lt;p&gt;{item.description}&lt;/p&gt;
    {/each}
{:catch error}
	&lt;p style=&quot;color: red&quot;&gt;{error.message}&lt;/p&gt;
{/await}

You can read more here: https://svelte.dev/tutorial/await-blocks

huangapple
  • 本文由 发表于 2023年4月20日 01:09:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76057166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定