0

I am a Reactjs noob and have an object with the structure below. In my functional component I would like to use the most modern approach to iterating through the keys at the top level in the object hierarchy (i.e. A, B, C) and display the value associated with the 'name' keys.

data.json

  {
  "A": {
    "name": "AA",
    "type": "AB",
    "values": [
      ["AC", "AD", "AE"],
      ["AF", "AG", "AH"]
    ]
  },
  "B": {
    "name": "BA",
    "type": "BB",
    "values": [
      ["BC", "BD", "BE"],
      ["BF", "BG", "BH"]
    ]
  },
  "C": {
    "name": "CA",
    "type": "CB",
    "values": [
      ["CC", "CD", "CE"],
      ["CF", "CG", "CH"]
    ]
  }
}

My desired result is to display the following on screen:

A - AA
B - BA
C - CA

I have attempted to do this using the map function, but I later read that map only works with arrays, not objects? I've also tried this answer: https://stackoverflow.com/a/14810722/679841 but conscious that (a) I wasn't able to get it to work in my case, perhaps because my object is a little bit more complex and I'm new to this, and (b) there have been a few updates which makes me wonder whether there is an even better approach now?

Here is a simplified veresion of my functional component.

FunctionalComponent.js

import React from 'react';
import Data from './data.json'; //See above for content of this json file
const data= Data; //not sure if this is necessary?!

    function Loop(){
    <form>
        return(
        //This is where I want to start my loop and dynamically populate
            <div>{data.A.name} - {data.A.name}</div>
        //This is where I want to end the loop
        );
        </form>
    }
    export default Loop;

Any help to achieve my desired result would be much appreciated.

Many thanks,

Katie

Katie7
  • 759
  • 1
  • 19
  • 34

2 Answers2

3

See this..

All Objects in JavaScript, can very well be treated as arrays. In your case, when you use Object.keys() or Object.values(), it will only return keys or values.. not both..

So use Object.entries()

https://codesandbox.io/s/object-represented-as-array-zgiob

Barun Patro
  • 860
  • 4
  • 13
  • Thanks so much Barun for creating a working version of this. I have had to edit my question slightly as I realise that I need my loop to work within the return function (see change in FunctionalComponent.js above). Have you got any guidance given this change? Thank you again :) – Katie7 Mar 12 '20 at 11:34
  • 1
    @Katie7, Do you mean like this?? https://codesandbox.io/s/array-of-refs-using-functional-components-yeh8t – Maniraj Murugan Mar 12 '20 at 11:41
  • @Katie7.. i had done the same. probably u got confused between 2 returns.. anyways updated the fork for you.. you can check again. – Barun Patro Mar 12 '20 at 11:45
  • Wohoo! You are geniuses! Thanks Barun for your reply and creating the example based on my initial question. And Maniraj - you adapted the code to work with my change and this worked, so thank you very much as well. Really appreciate you taking the time to help. Katie – Katie7 Mar 12 '20 at 11:52
0

Try this-

    class TestApp extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            items: {
                "A": {
                    "name": "AA",
                    "type": "AB",
                    "values": [
                        ["AC", "AD", "AE"],
                        ["AF", "AG", "AH"]
                    ]
                },
                "B": {
                    "name": "BA",
                    "type": "BB",
                    "values": [
                        ["BC", "BD", "BE"],
                        ["BF", "BG", "BH"]
                    ]
                },
                "C": {
                    "name": "CA",
                    "type": "CB",
                    "values": [
                        ["CC", "CD", "CE"],
                        ["CF", "CG", "CH"]
                    ]
                }
            }
        }
    }

    render() {
        return (
            <React.Fragment>
                {this.state.items
                    && Object.keys(this.state.items).map((key, i) =>
                        <div>{key}-{this.state.items[key].name}</div>
                    )}
            </React.Fragment>
        )
    }
}

ReactDOM.render(<TestApp />, document.querySelector("#app"))

https://jsfiddle.net/anupdg/0kv5erqd/7/

Anup Das Gupta
  • 772
  • 1
  • 7
  • 24
  • Thank you Anup for taking the time to help - as I am using a functional component rather than a class-based one, I have gone with the answer provided by Barun and Maniraj above, but perhaps your response will help someone else who would like a class-based answer! :-) Thanks again – Katie7 Mar 12 '20 at 11:54