lakeIn231
lakeIn231

Reputation: 1295

Trying to iterate over a JSON object in React

I am trying to display a toggle checkbox for every JSON value I have. This is what the json object looks like for element

{
    "sourceIP": {
        "Primary": ["237.100.100.3", "238.0.4.8"],
        "Secondary": ["237.0.1.178", "237.1.1.91"]
    },
    "multicastIP": {
        "Primary": ["10.208.153.129", "238.0.4.8"],
        "Secondary": ["10.208.133.58", "238.0.4.8"]
    }
}

So I would like to iterate through element instead of hardcoding it like this:

const CustomToggle = ({ element}) => (
<List divided verticalAlign='middle'>
    <Segment textAlign='left' style={{paddingLeft: '7.5em'}}>
        <Checkbox
            toggle
            label={(JSON.stringify(element.sourceIP.Primary[0]))}
            value={(JSON.stringify(element.sourceIP.Primary[0]))}
        />
        <Checkbox
            toggle
            label={(JSON.stringify(element.sourceIP.Primary[1]))}
            value={(JSON.stringify(element.sourceIP.Primary[1]))}
        />
        <Checkbox
            toggle
            label={(JSON.stringify(element.sourceIP.Secondary[1]))}
            value={(JSON.stringify(element.sourceIP.Secondary[1]))}
        />
    </Segment>

</List>

);

I have been trying to forEach and .map but none of this seems to work. I don't want to have to hardcode every json value in element. How can I just iterate through my element JSON object?

Upvotes: 0

Views: 103

Answers (3)

user13198697
user13198697

Reputation:

Object.keys(element).reduce((a,c) => a.concat(...Object.values(element[c])),[])

this transformed data gives array of ip adtresses. So, now you can iterate it

const CustomToggle = ({ element}) => {
  const elements = Object.keys(element).reduce((a,c) => a.concat(...Object.values(element[c])),[]); 
  return (
    <List divided verticalAlign='middle'> 
       <Segment textAlign='left' style={{paddingLeft: '7.5em'}}>
          {elements.map(ip => <Checkbox toggle label={ip} value={ip} />}
        </Segment> 
     </List>
  )
}

Upvotes: 2

Lu&#237;s Ramalho
Lu&#237;s Ramalho

Reputation: 10198

You can for example do something like the snipped below:

const List = ({ divided, rest }) => <div {...rest} />;
const Checkbox = ({ toggle, ...props }) => (
  <div>
    <input type="checkbox" {...props} />
    <label>{props.label}</label>
  </div>
);
const Segment = (props) => <div {...props} />;

const CustomToggle = ({ element }) => (
  <div>
    {element.map((ip) => (
      <Checkbox toggle label={ip} value={ip} />
    ))}
  </div>
);

function App() {
  let result = `{
        "sourceIP": {
            "Primary": ["237.100.100.3", "238.0.4.8"],
            "Secondary": ["237.0.1.178", "237.1.1.91"]
        },
        "multicastIP": {
            "Primary": ["10.208.153.129", "238.0.4.8"],
            "Secondary": ["10.208.133.58", "238.0.4.8"]
        }
    }`;
  let data = JSON.parse(result);
  let ips = [];
  Object.keys(data).map((source) => {
    Object.keys(data[source]).map((type) => {
      ips.push(...data[source][type]);
    });
  });
  return <CustomToggle element={ips} />;
}

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

So, you'll parse the data, then iterate over it to get the IPs and then pass those as a prop to the CustomToggle. The code above is just an example to get you going as I don't know what your List, Checkbox and Segment components look like.

The reasoning is that CustomToggle should not know or care what the data should look like, it just knows how to render a custom toggle based on some string that it receives, in this case the ip. You should however make sure that each Checkbox has a unique key.

Upvotes: 0

rzwnahmd
rzwnahmd

Reputation: 1082

Here try this, let me know if it helps :)

const CustomToggle = ({ element }) => (
  <List divided verticalAlign="middle">
    <Segment textAlign="left" style={{ paddingLeft: "7.5em" }}>
      {Object.keys(element).map(key => {
        return [...element[key].Primary, ...element[key].Secondary].map(x => {
          <Checkbox toggle label={x} value={x} />;
        });
      })}
    </Segment>
  </List>
);

Upvotes: 0

Related Questions