Noble Polygon
Noble Polygon

Reputation: 806

Mapping JSON data with React Hooks

I'm working on a small project and I am trying to map data from a JSON file into my project. In components with nested data, I keep getting an let data = props.data["runways"];.

data.json:

{
   "runways":[
      {
         "slot":"Area 1",
         "planes":[
            {
               "name":"PanAm",
               "number":"12345",
               "start":{
                  "time":1585129140
               },
               "end":{
                  "time":1585130100
               }
            },
            {
               "name":"PanAm 222 ",
               "number":"12345",
               "start":{
                  "time":1585129140
               },
               "end":{
                  "time":1585130100
               }
            }
         ]
      }
   ]
}

App.js,

I pass the JSON data as props:

import planeData from './plane_info.json'


const Container = () => {

    const [planeDataState, setPlaneDataState] = useState({})
    const planeData = () => setPlaneDataState(planeData[0].runways)
    return (
           <>
            <MyPlane planeInfo={planeDataState}/>
            <button onClick={planeData} type="button">Get Data</button>
           </>
       )
}

and finally, I want to bring my data into my component:

MyPlane.jsx

const MyPlane = (props) => {
    let data = props.data["runways"];
    if(data)
        console.log(data, 'aaa')
        return (
            <>
                {
                    data ? (
                        <div>
                        <span>{props.planeInfo.name}</span>
                        <span>RAIL TYPE: {props.planeInfo.type}</span>
                        </div>
                    ) : <h6>Empty</h6>
                }
            </>
        );
}

According to the error message, the problem occurs at this line of code: let data = props.data["runways"]; However, I believe that I am passing the data for runways from the JSON file. I've never worked with React Hooks to pass data, so I'm confused about why this error is occurring.

Upvotes: 1

Views: 6780

Answers (3)

amdev
amdev

Reputation: 7442

At the beginning there is no data in props.data['runways'] (also you can use props.data.runways, I guess you come from another language like Python as of this syntax that you are using), because you sent the request at first, it takes time for request to be satisfied, so you need to check in your <MyPlane /> component to see if there is a runways key in data and then proceed to render the component, something like below:

const MyPlane = (props) => {
    const data = props.data
    return (
      <>
        {
          data.runways
            ? <>
                ...your render able items that you wrote before
              </>
            : <p>There is no data yet!</p>
        }
      </>
    )
}

Also please note that you might return something from component. At your case your render is inside the if(data){...} statement! what if the condition was not satisfied? which is your current error case !

NOTE: please check that you are passing your planeDataState as planeInfo prop to the child component, so you might have something like:

const data = props.planInfo

to be able to use the data variable that you've defined before the render part.

Upvotes: 0

Juan Marco
Juan Marco

Reputation: 3241

In order to map effectively over the JSON data it's necessary to understand how that data structure is composed.

If you're unsure, using JSON.stringify() is a great way to get the "bigger picture" and then decide what exactly is it that you want to display or pass down as props to other components.

It appears you wish to get the plane data (which is currently an array of 2 planes). If so, you could first get that array, set the state, then map over it to display relevant info. Perhaps like this:

const data = {
  "runways":[
     {
        "slot":"Area 1",
        "planes":[
           {
              "name":"PanAm",
              "number":"12345",
              "start":{
                 "time":1585129140
              },
              "end":{
                 "time":1585130100
              }
           },
           {
              "name":"PanAm 222 ",
              "number":"12345",
              "start":{
                 "time":1585129140
              },
              "end":{
                 "time":1585130100
              }
           }
        ]
     }
  ]
}

function App() {

  const [ planeData, setPlaneData ] = React.useState(null)

  React.useEffect(() => {
    setPlaneData(data.runways[0].planes)
  }, [])

  return (
    <div className="App">
      {/* {JSON.stringify(planeData)} */}
      {planeData && planeData.map(p => (
        <p key={p.name}>
          {p.name} | {p.number} | {p.start.time} | {p.end.time}
        </p>
      ))}
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'))
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

Upvotes: 2

Puja Srivastava
Puja Srivastava

Reputation: 336

Here const planeData = () => setPlaneDataState(planeData[0].runways)

In this line, planeData[0].runways will be undefined according to the json file which you have shared.

Instead try setting and passing entire json object, ie,

const planeData = () => setPlaneDataState(planeData)

Try this, And then inside MyPlane.jsx component, let data = props.data["runways"]; this won't be undefined. So , the error won't come.

Upvotes: 1

Related Questions