0

hi guys I'm trying to extract data from this:

1) […]
​
0: {…}
​​
__v: 0
​​
_id: "5ba96b8ebffd923734090df4"
​​
formID: "5ba96b83bffd923734090df0"
​​
inputArr: Array(3) [ "value1", "value2", "value3" ]
​​
labelArr: Array(3) [ "label1", "label2", "label3" ]
​​
<prototype>: Object { … }
​
length: 1
​
<prototype>: Array []

I need to get to the array inside the data, which is this.state.inputData (what you see above is the content),

I tried

const labels = inputDataArr[0].labelArr.map((r, index) => {
      return (
        <tr key={index}>
          <th>{index}</th>
          <th>{r[index]}</th>
        </tr>
      );

but I get item undefined, anybody knows why?

EDIT : additional problem rendering :

renderData(i) {
    const { inputDataArr } = this.state;
    return (
      !!inputDataArr.length &&
      inputDataArr[i].inputArr.map((input, index) => (
        <th key={index}>{input}</th>
      ))
    );
  }
  countLength() {
    const { inputDataArr } = this.state;
    return !!inputDataArr.length && inputDataArr[0].inputArr.length;
  }
  runThrough() {
    for (let i = 0; i < this.countLength; i++) return this.renderData(i);
  }
  render() {
    const data = this.runThrough();
    return (
      <div className="app">
        <table>
          <tr>{this.renderLabels()}</tr>
          {data}
        </table>
      </div>
    );
  }
}
8
  • 2
    You have mistaken r in your mapping as an array, it is actually one of the inputArr values. Commented Sep 25, 2018 at 0:05
  • Im sorry i dont understand, inputDataArr is an array, I take the [0] one which is an object, and I go for the array which is labelArr Commented Sep 25, 2018 at 0:12
  • The html here <th>{r[index]}</th> should be <th>{r}</th> Commented Sep 25, 2018 at 0:16
  • I get this error : this.state.inputDataArr.labelArr is undefined even tho this.state.inputDataArr is defined and I can see the structure that I posted above. Commented Sep 25, 2018 at 0:21
  • Try const labels = inputDataArr.labelArr instead of inputDataArr[0] incase it is not an array. Commented Sep 25, 2018 at 0:27

1 Answer 1

1

Given the same example from your other question. Not quite sure this suits you as it is, maybe you need to change and think about it a little bit.

class App extends React.Component {
  state = {
    inputDataArr: [
      {
        formID: "3",
        inputArr: [ "value1", "value2" ],
        labelArr: [ "label1", "label2" ],
      },
      {
        formID: "3",
        inputArr: [ "value3", "value4" ],
        labelArr: [ "label3", "label4" ],
      },
    ],
  }


  renderLabels() {
    const { inputDataArr } = this.state;
    return !!inputDataArr.length && inputDataArr[ 0 ].labelArr.map( ( label, index ) =>
      ( <tr key={label}>
        <th>{index}</th>
        <th>{label}</th>
        </tr> ) );
  }

  render() {
    return (
      <div>
        <table>
          {this.renderLabels()}
        </table>
      </div>
    );
  }
}

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

Update after comments

After learning that you are getting the data via an async operation, I've added a small condition to the renderLabels method. Now it looks for if the array's length returns true:

return !!inputDataArr.length && inputDataArr[ 0 ]

This is a mix of logical operators and React's rendering logic. Why I use !!inputDataArr.length instead of inputDataArr.length?

Normally, in logical operators, if the first condition is 0 then it does not pass the second part.

const num = 0;

num && console.log( "passed the second part" );

As you can see it never passes the second part. This is because 0 means false here.

React ignores rendering if a value is undefined or false or null. But it renders if a value is 0 :)

Let's see:

class App extends React.Component {
  state = {
    num: 0,
  };


  render() {
    return (
      <div>
        {this.state.num && <p>Render me</p>}
      </div>
    );
  }
}

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

This is similar to your situation. In the first render array's length is 0. So, if we use this:

return inputDataArr.length && inputDataArr[ 0 ]

it renders a 0. What we want here is ignore the rendering. So if we use logical NOT operator twice we get a false here and React ignores rendering. Why we get false?

Since 0 means false, !!false again evaluated to false. Then, React ignores rendering and we are safe from the error that you provided in your question.

When the data lands your app, in the second render this time array's length is greater than 0, let's say 2. !!2 evaluates to true then React renders the second part of the condition, your label array.

You can write your condition like this if you want:

renderLabels() {
  const { inputDataArr } = this.state;
  if (inputDataArr.length > 1) {
    return inputDataArr[0].labelArr.map((label, index) => (
      <tr key={label}>
        <th>{index}</th>
        <th>{label}</th>
      </tr>
    ));
  }
}
Sign up to request clarification or add additional context in comments.

17 Comments

thank you for your help, but the last question I just filtered the once I dont need, I get an array of objects with the ID of 3, so for this example all of the objects have the ID of 3, and all of their labelArr is the same, I just want to make a table containing all of those labels in the array.
How same? All of them are like [ "label1", "label2", "label3" ]? So this is the only array you want to map?
In case you can't come to the chat discussion, here is conditional rendering part of the official documentation. If !! part confused you I am going to add a simpler if method in a minute.
Do not widen your old questions like that :) Ask a new question and try to give all the details there. Also, do not bother with for loops, use map or other methods. I won't be here for a while but when you ask a new question and give good details people will try to help.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.