es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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”
}

Tags:  , , ,

Answer

  1. Avatar for 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, y Object.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í:

    <!-- primer intento -->
    {#if hasData}
      <div>
        {#await json}
          Cargando...
        {:then json}
          {#each Object.values(json) as user}
            El nombre es {user.lang}
          {/each}
        {:catch error}
          <p style="color: red">{error.message}</p>
        {/await}
      </div>
    {/if}
    
    <!-- segundo intento -->
    {#if hasData}
      {#each Object.entries(json) as [key, value]}
        <tr>
          <td>{key}</td>
          <td>{value.lang}</td>
        </tr>
      {/each}
    {:else}
      Cargando...
    {/if}
    

    Ten en cuenta que en el segundo intento, estamos deconstruyendo el array [key, value] para obtener las propiedades key y value.lang para mostrar en la tabla. La key representa el ID generado dinámicamente para cada objeto en la respuesta JSON.

Comments are closed.