BearsBeetBattlestar
BearsBeetBattlestar

Reputation: 318

React - Nested maps to retrieve json data

So I'm a bit new to javascript and react in general, so I've been practicing. Right now I was trying to retrieve JSON data and use that to render multiple HTML blocks pretty much like a basic schedule. For example, initially, my JSON was formatted as so

{
  "saturday":[
  {
    "event": 1
  },
  {
    "event": 2
  }
 ]
}

and I used a function like the following to map for each part of the JSON array

initialize = events => {
  return events.map(this.createBlock)
}

Here createBlock is another function returning the following.

createBlock = events =>{
 return(
    <Scheduled
       event={events.event}   
    />
 );

this way when calling the initialize function in render It would create two event blocks but according to the individual data from createBlock in this case just the event number (Scheduled is just the file in which I format how the data from createBlock will be returned as with styling).

And I called all of this in my jsx with

{this.initialize(data.saturday)}

where data is the JSON asset imported in

But now I wanted to do the same but on nested JSON data. So it would look like this. So now instead of directly make multiple event blocks. It would make multiple time blocks each with multiple event blocks inside of them.

"saturday":{
  "time":{
    "9:00": [
      {
        "event": 1
      },
      {
        "event": 2
      }
    ],
    "10:00":[
      {
        "event": 1
      },
      {
        "event": 2
      }
    ]
  }
}

I'm just confused on how to approach this. I was thinking about maybe a nested map but wasn't sure if that was practical. Any advice/help would be appreciated, Thanks.

Upvotes: 2

Views: 1377

Answers (2)

Shubham Khatri
Shubham Khatri

Reputation: 281686

At first level, you have an object and at the second level is the array and hence in order to use map, you need to make use of Object.entries(it returns an array of arrays as key value pairs) at the first level

initialize = day => {
  return Object.entries(day.time).map(this.createBlock)
}

createBlock = ([time, events]) =>{
 return (
     <div>
        <p>{time}</p>
       {events.map(this.createEvent)}
     </div>
 );

createEvent = event =>{
 return(
    <Scheduled
       event={event.event}   
    />
 ); 

const data = {
  "saturday": {
    "time": {
      "9:00": [{
          "event": 1
        },
        {
          "event": 2
        }
      ],
      "10:00": [{
          "event": 1
        },
        {
          "event": 2
        }
      ]
    }
  }
}

const Scheduled = ({
  event
}) => {
  return <div > {
    event
  } < /div>
}

class App extends React.Component {

  initialize = day => {
    return <div > {
      Object.entries(day.time).map(this.createBlock)
    } < /div>
  }

  createBlock = ([time, events]) => {
    return ( <
        div key = {
          time
        } >
        <
        p > {
          time
        } < /p> {
        events.map(this.createEvent)
      } <
      /div>
  );
}

createEvent = event => {
  return ( <
    Scheduled key = {
      event.event
    }
    event = {
      event.event
    }
    />
  )
}


render() {
  return ( <
    div > {
      this.initialize(data.saturday)
    } <
    /div>
  )
}
}

ReactDOM.render( < App / > , document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="app" />

Upvotes: 5

Anantha kumar
Anantha kumar

Reputation: 375

Sure you can go with nested map.

initialize = timings => { return timings.map(this.createEvents) }

then

createEvents = events => { return events.map(this.createBlock) }

finally

{this.initialize(data.saturday)}

Upvotes: 2

Related Questions