1

I have the following JSON file called 'testing_numbers.json':

 [{ "number":1,
"number":2,
"number":3,
"number":4,
"number":4,
"number":5,
"number":6,
"number":7,
"number":9,
"number":10,
"number":11}]

All I want to do is push each value to a list through a for loop, then append the list. My React code is like so:

import React, { Component } from 'react';
let values = require('./test_numbers.json');


class App extends Component {
  state = {  }
  render() { 
    const numbers = []
    for (var x in values) {
      numbers.push(values[x].number)
    }
    return ( numbers );
  }
}

export default App;

All I get as an output is the last variable in the JSON (which is 11), and not anything before that. It seems like I have something fundamentally wrong.

I am aware that I could just map the JSON first and then render it, but for my application, it would be better if I extracted data one at a time.

If anyone could help that would be great

Dexygen
  • 12,287
  • 13
  • 80
  • 147
freeza
  • 13
  • 5

3 Answers3

3

The problem isn't the loop, it's the JSON. Your JSON is an array with just one entry, which is a single object with eleven property definitions all using the same name. The result of parsing that JSON is an array with an object with a single property, whose value is the value from the last property definition using the name. You can't reuse the name number like that within the object, you need different names for the properties.

Perhaps you wanted the JSON to have an array with multiple objects in it:

[
    {"number":1},
    {"number":2},
    {"number":3},
    {"number":4},
    {"number":4},
    {"number":5},
    {"number":6},
    {"number":7},
    {"number":9},
    {"number":10},
    {"number":11}
]

Separately: for-in isn't the correct tool for looping through arrays. See my answer here for your various options for what to use instead. For instance, if I'm right that you meant to have an array of eleven objects, then:

const numbers = values.map(entry => entry.number);

const values = [
    {"number":1},
    {"number":2},
    {"number":3},
    {"number":4},
    {"number":4},
    {"number":5},
    {"number":6},
    {"number":7},
    {"number":9},
    {"number":10},
    {"number":11}
];

class App extends React.Component {
  state = {  }
  render() { 
    const numbers = values.map(entry => entry.number);
    return numbers; // No need for () around it
  }
}

ReactDOM.render(
  <App />,
  document.getElementById("root")
);
.as-console-wrapper {
  max-height: 100% !important;
}
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

There is no meaning of having same keys with different values in single object, an object should contain unique key names to simplify your case

Change the json to something like below

   [1,2,3,4,5,6,7,8,9,10,11]

And

   render() { 
     const numbers = []
     for (var x in values) {
          numbers.push(<span key={x}>{x}</span>);
     }
     return ( {numbers} );
  }

Or simply

   render() { 
     return ( 
          {values.map(val => <span key={val}>{val}</span>)}
     );
  }

Or make it individual object for each number. But I don’t see any meaning of having same key with different number in each object instead keep them as array of numbers instead of objects

Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162
  • Or, you know, `const numbers = values.slice();` ;-) Good point that if the OP just wants the numbers, having objects doesn't make a lot of sense. – T.J. Crowder Nov 10 '18 at 13:32
  • I tried doing this, but I am getting a separate error now, which is "Objects are not valid as a React child (found: object with keys {number}). If you meant to render a collection of children, use an array instead" – freeza Nov 10 '18 at 14:21
  • The `{numbers}` in the first example and `{values.map(...)}` in the second are syntax errors, they aren't within a JSX element. You need to remove the `{` and `}`. @freeza - that's why you're getting that error. – T.J. Crowder Nov 10 '18 at 15:01
0

I won't go over the issue since TJ's answer covers that. But here's some working code that uses an array of objects (instead of a single object in an array with all the same property keys). It uses map to produce a new array of numbers from the array of objects. Here I've used a <ul> container and returned the numbers in <li> elements.

const data = [{"number":1},{"number":2},{"number":3},{"number":4},{"number":4},{"number":5},{"number":6},{"number":7},{"number":9},{"number":10},{"number":11}]

class App extends React.Component {
  render() {
    return (
      <ul>
        {data.map(el => <li>{el.number}</li>)};
      </ul>
     )
  }
}

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>
Andy
  • 61,948
  • 13
  • 68
  • 95