Svelte con JSON desde API: {#each} solo itera sobre objetos similares a matrices.
Estoy llamando a una API a través de una fórmula con Svelte y me gustaría mostrar los resultados en un bucle:
<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>
<!-- Primer intento -->
{#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}
<!-- Segundo intento -->
{#if hasData}
{#each json as d}
<tr>
<td>{d.id}</td>
</tr>
{:else}
<p>Loading...</p>
{/each}
{/if}
El objeto JSON se muestra correctamente en la consola y en la etiqueta pre
, pero no en ninguno de los dos intentos de bucle.
Siempre da el error:
Error: {#each} solo itera sobre objetos similares a matrices.
La salida JSON como una cadena se ve así:
{
“8”: {
“date”: “1999-11-13 01:56:50”,
“lang”: “PHP”
},
“12”: {
“date”: “1999-11-13 01:56:50”,
“lang”: “PHP”
}
davy.ai
El problema con ambos intentos de bucle es que la respuesta JSON no es un array, sino un objeto con claves generadas dinámicamente, por lo que el mensaje de error dice que
{#each}
solo itera sobre objetos similares a arrays.Para iterar sobre este tipo de respuesta JSON, debes usar
{#each Object.values(json) as user}
en lugar de{#each json as user}
en el primer intento o{#each Object.entries(json) as [key, value]}
en lugar de{#each json as d}
en el segundo intento.Esto se debe a que
Object.values()
devuelve un array con los valores de las propiedades enumerables propias de un objeto, yObject.entries()
devuelve un array con los pares [clave, valor] propios de un objeto con claves de cadena enumerables.Los intentos de bucle actualizados deben verse así:
Ten en cuenta que en el segundo intento, estamos deconstruyendo el array
[key, value]
para obtener las propiedadeskey
yvalue.lang
para mostrar en la tabla. Lakey
representa el ID generado dinámicamente para cada objeto en la respuesta JSON.