0

I am trying to loop through an array and render the data inside an element. I am using ReactJs.

My data array:

var data = [{
      type: "Academic",
      time: "2015 - 2016",
      title: " MSc Software Engineering",
      place: "University of Oxford",
      description: "Lorem impsum",
      gallery: [
        {url: "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/v/t1.0-1/p160x160/10923196_10204583699694173_6145976884213630323_n.jpg?oh=bd235908314ecf0ab5afa8d3f92f5abf&oe=567B51F9&__gda__=1450897067_285c7c8c720c0f130453b37e9ff9b2f8"}
      ]
    }

Array where data is supposed to be pushed to:

var events = []

Loop:

for (var i = 0; i < data.length; i++) {
      var directions;
      if (data[i] % 2 == 0) {
        directions = "direction-r";
      } else {
        directions = "direction-l"
      }
      events.push(
        <li>
          <TimelineEvent type={data[i].type}
            time = {data[i].time}
            title = {data[i].title}
            place = {data[i].place}
            description = {data[i].description}
            direction = {directions}/>
        </li>
      )
    }

How the rendered data needs to look like:

<li>
  <TimelineEvent
     type = "Academic"
     time = "2015 - 2016"
     title = "MSc Software Engineering",
     place = "University of Oxford",
     description = "Lorem ipsum"
     direction = "direction-r" />
</li>
<li>
  <TimelineEvent
     type = "Academic"
     time = "2015 - 2016"
     title = "MSc Software Engineering",
     place = "University of Oxford",
     description = "Lorem ipsum"
     direction = "direction-l" />
</li>

The "direction" has to be either "r" or "l" for even and odd elements.

I am getting the error:

TypeError: Cannot read property 'type' of undefined
   at Timeline.render (/Users/hilarl/Desktop/client/build/webpack:/src/components/ProfilePage/Layout/Main/Main.js:102:41)
   at [object Object].ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (/Users/hilarl/Desktop/client/node_modules/react-dom/node_modules/react/lib/ReactCompositeComponent.js:546:34)
   at [object Object].ReactCompositeComponentMixin._renderValidatedComponent (/Users/hilarl/Desktop/client/node_modules/react-dom/node_modules/react/lib/ReactCompositeComponent.js:566:32)
   at [object Object].wrapper [as _renderValidatedComponent] (/Users/hilarl/Desktop/client/node_modules/react-dom/node_modules/react/lib/ReactPerf.js:66:21)
   at [object Object].ReactCompositeComponentMixin.mountComponent (/Users/hilarl/Desktop/client/node_modules/react-dom/node_modules/react/lib/ReactCompositeComponent.js:181:32)
   at [object Object].wrapper [as mountComponent] (/Users/hilarl/Desktop/client/node_modules/react-dom/node_modules/react/lib/ReactPerf.js:66:21)
   at Object.ReactReconciler.mountComponent (/Users/hilarl/Desktop/client/node_modules/react-dom/node_modules/react/lib/ReactReconciler.js:37:35)
   at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (/Users/hilarl/Desktop/client/node_modules/react-dom/node_modules/react/lib/ReactMultiChild.js:207:44)
   at ReactDOMComponent.Mixin._createContentMarkup (/Users/hilarl/Desktop/client/node_modules/react-dom/node_modules/react/lib/ReactDOMComponent.js:541:32)
   at ReactDOMComponent.Mixin.mountComponent (/Users/hilarl/Desktop/client/node_modules/react-dom/node_modules/react/lib/ReactDOMComponent.js:438:27)

I am not really a JS pro so I may not be doing this right. Any idea what is wrong here? Thanks a lot

3 Answers 3

1

Maybe try:

for (var i = 0; i < data.length; i++) {
      var directions;
      if (data[i] % 2 == 0) {
        directions = "direction-r";
      } else {
        directions = "direction-l"
      }
      events.push(
        <li>
          <TimelineEvent type={data[i].type}
            time = {data[i].time}
            title = {data[i].title}
            place = {data[i].place}
            description = {data[i].description}
            direction = {directions}/>
        </li>
      )
    } 

Also rather than or for loop you could use forEach

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that seemed to work. But the part: if (data[i] % 2 == 0) { directions = "direction-r"; } else { directions = "direction-l" } does not seem to have any affect. Is it as it should be?
@kostbone answer above will fix that part
1

One more thing, you should probably change is following line of code

if (data[i] % 2 == 0)

it should be if (i % 2 == 0), because data[i] will return object from the data array

Comments

0

It's already been answered, but if you want to taste some functional code:

var events = data.map(function (datum, index) {
    var directions = 'direction-'; 
    directions += index % 2 === 0 ? 'r' : 'l';
    return (
         <li>
             <TimelineEvent 
                 type={datum.type}
                 time={datum.time}
                 title={datum.title}
                 place={datum.place}
                 description={datum.description}
                 direction={directions} 
              >
                 { datum.gallery.map(function (link) {
                     return (
                         <a href="#">
                           <img 
                               className="timelineGalleryImage" 
                               src={link.url} />
                         </a>
                     );
                 } }
             <TimelineEvent />
        </li>
    );
})

2 Comments

Thanks gcedo, the code looks a lot more cleaner with this approach. I am getting the error: TypeError: Cannot read property 'map' of undefined. And, is it possible for you to explain how I could iterate over the gallery: [] for each event? I am trying to display it as <a href="#"><img className="timelineGalleryImage" src={data[i].gallery[j].url} /></a>
The first error is there because data is undefined, check before that point. I have updated the answer, I tried to understand what you wanted to achieve.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.