Bonjour,

Je rencontre un petit problème avec mon code.

Voilà je cherches à afficher une propriété de plusieurs objets d'un fichier json local. J'utilises la méthode fonctionnelle, avec les hooks de React. Voici à quoi mon ficher jsx ressemble

import grounds  from './../../UballersGroundsData.json';
import { useState, useEffect } from 'react';

export default function Groundlist() {
    const [names, setNames] = useState([]);

    useEffect(() => {
        function getNames(jsonObj){
            for(let item in jsonObj){
                console.log("item = " + item);
                for(let property in jsonObj[item] ){
                    console.log(jsonObj[item]);
                     if (property === "groundName"){
                        console.log(jsonObj[item][property]);
                     }

                }
            }       
        }
        const result = getNames(grounds);
        setNames(result)
    }, [])

    return(
        <div>
            <h1>Hello world!</h1> 
            <ul>
                {Array.from(names).map(name => <li>{name.groundName}</li>)}
            </ul>
        </div>
    )
}

et voici à quoi ressemble une partie du fichier json

{
  "ground1":{
    "groundId": "2",
    "city": "Paris",
    "country": "France",
    "groundName": "Bir-Hakeim",
  },
  "ground2":{
    "groundId": "26585",
    "city": "Bordeaux",
    "country": "France",
    "groundName": "1 Rue du Petit Cardinal",
  }
}

J'éssaie d'afficher sous forme de liste tout les "groundName".
Je suis près à refaire totalement le fichier jsx bien sur.

Malheureusement, les objets ground# se rendent plusieurs fois, au lieu d'une seul fois quand la fonction est appelée. Et en plus j'obtiens cette erreur "TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator)) ".

Merci à vous =)!

1 réponse


Salut, tu n'étais pas loin tu t'es juste planté sur ta second boucle, ça ne retournais qu'un objet

    import grounds  from './../../UballersGroundsData.json';
    import React, { useState, useEffect } from 'react';

    export default function Groundlist() {
        const [names, setNames] = useState([]);

        useEffect(() => {
          function getNames(jsonObj) {
            let result = [];
            for (let item in jsonObj) {
              for (let property in jsonObj[item]) {
                if (property === "groundName") {
                  result.push(jsonObj[item].groundName);
                }
              }
            }
            return result;
          }

          const result = getNames(grounds);
          setNames(result);
        }, []);

        return(
            <div>
                <h1>Hello world!</h1>
                <ul>
                   {names.map((name) => (
                      <li>{name}</li>
                   ))}
                </ul>
            </div>
        )
    }   

Sinon ce serait beaucoup plus simple pour toi si tu revoyais un peu ton json comme ceci

    [
      {
        "ground": { // Peut être à supprimer étant donné que tu à un ID différent pour chaque objet
          "groundId": "2",
          "city": "Paris",
          "country": "France",
          "groundName": "Bir-Hakeim"
        }
      },
      {
        "ground": {
          "groundId": "26585",
          "city": "Bordeaux",
          "country": "France",
          "groundName": "1 Rue du Petit Cardinal"
        }
      }
  ]

Ca te permetterai de faire ceci

    import grounds  from './../../UballersGroundsData.json';
    import React, { useState, useEffect } from 'react';

    export default function Groundlist() {
        const [names, setNames] = useState([]);

         useEffect(() => {
            setNames(grounds.map((obj) => obj.ground.groundName));
        }, []);

        return(
            <div>
                <h1>Hello world!</h1>
                <ul>
                    {names.map((name) => (
                      <li>{name}</li>
                    ))}
                </ul>
            </div>
        )
    }

ou directement

        import grounds  from './../../UballersGroundsData.json';
        import React from 'react';

        export default function Groundlist() {
            return(
                <div>
                    <h1>Hello world!</h1>
                    <ul>
                        // Tu destructure 2 fois ton objet (1 fois sur la clé ground, 1 fois sur les propriétées de ground pour récup groundName
                        {grounds.map(({ ground: { groundName } }) => ( 
                            <li>{groundName}</li>
                         ))}
                    </ul>
                </div>
            )
        }

Bon courage pour la suite