0

I am learning React-Redux and I have an issue navigating through the objects in my JSON file. I have the following file JSON, the file is designed to render out a side navigation:

export default function(){
    return [
            {
            catId:"parMenu1",
            parentCat:"Genres",
            subcat:[
                {
                    genre:"8Bit",
                    genreId:"1"
                },
                {
                    genre:"Acid House",
                    genreId:"2"
                }
           ]
           },
           {
            catId:"parMenu2",
            parentCat:"sounds",
            subcat:[
                {
                    genre:"blah",
                    genreId:"3"
                },
                {
                    genre:"blah House",
                    genreId:"4"
                }
           ]
    ]
}

I have the JSON file mapped to state props for a component. The component looks like so:

class BrowseByCont extends Component {  
    render () {
        return (
            <div className="browseByContInner">
                {
                    console.log(this.props.reducerSidenav[0].catId)
                }
            </div>
        )
    }
}


function mapStateToProps(state) {
    return {
        reducerSidenav:state.reducerSidenav
    };
} 

I am trying to reach the subcats object within the parent object. The JSON object is linked to a variable called "reducerSidenav". So far I have managed to get this far into my JSON file: this.props.reducerSidenav[0].catId. this spits out the value parMenu1 which is the "parent" object I want to target. Where I am stuck though is I am trying to achieve two things:

firstly - I would like to access the first "parent" object by without having to refer to the first item in the array: reducerSidenav[0] but rather by find the catId with a value of parMenu1. This is because this list will be dynamic in future and referring to the first array object is not reliable.

secondy - I would then like to access the subcat object and get to the value thats associated to the key genre ie to return the value "8Bit"

  • 1
    There is no JSON above. JSON is a *textual notation* for data exchange. [(More)](http://stackoverflow.com/a/2904181/157247) If you're dealing with JavaScript source code, and not dealing with a *string*, you're not dealing with JSON. – T.J. Crowder Oct 13 '16 at 11:30
  • ok good to know and thanks for clarifying. Question still stands though –  Oct 13 '16 at 11:44

1 Answers1

1

You can use .find() to achieve both things.

class BrowseByCont extends React.Component {  
    render () {
        let first = this.props.reducerSidenav.find(item => item.catId === "parMenu1");
        let second = first.subcat.find(subcat => subcat.genre === "8Bit")
        return (
            <div className="browseByContInner">
                <div>{first.catId}</div>
                <div>{second.genre}</div>
            </div>
        )
    }
}

Edit

In order to print all the subcats, you have to use .map()

class BrowseByCont extends React.Component {  
    render () {
        let first = this.props.reducerSidenav.find(item => item.catId === "parMenu1");
        return (
            <div className="browseByContInner">
                {first.subcat.map(genreItem => 
                    <div key={genreItem.genreId}>{genreItem.genre}</div>)
                }
            </div>
        )
    }
}

jsfiddle

QoP
  • 27,388
  • 16
  • 74
  • 74
  • Good to know about find. I tried it before but I was using it in the wrong way I think. Your answer spits out the values that I want but not in the way that I want. I was wanting to map all the subcat items and return them into divs. I have written a fiddle here https://jsfiddle.net/74pgqby5/ of what I am trying to achieve. At the moment its giving me an error: A valid React element (or null) must be returned. so I guess i'm not targeting the map correctly? –  Oct 13 '16 at 12:23
  • this is the correct way to achieve what you want in that jsfiddle, https://jsfiddle.net/69z2wepo/59721/ – QoP Oct 13 '16 at 12:30
  • Thanks QoP that works but i'm confused as to how you are referencing "8Bit". Lets say that I change the object down the line and "8Bit" is no longer the first item in the subcats array. Would there be a more generic way of targeting the subcats array? –  Oct 13 '16 at 12:33
  • Sorry i just saw that the second let was not needed. Was confusing me. Do you want to post the answer or shall I? –  Oct 13 '16 at 12:36
  • if you could also tell me what the syntax item => is doing just after the .find( that would be really helpfull! Cheers –  Oct 13 '16 at 12:42
  • that's an `arrow function`, it's a new feature of ES6, [ES5 equivalent](http://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=true&presets=es2015%2Ces2015-loose%2Ces2016%2Ces2017%2Creact%2Cstage-0&experimental=false&loose=false&spec=false&code=let%20first%20%3D%20this.props.reducerSidenav.find(item%20%3D%3E%20item.catId%20%3D%3D%3D%20%22parMenu1%22)%3B) – QoP Oct 13 '16 at 12:45
  • ok and just before it you used "item". Are you declaring a function called item? –  Oct 13 '16 at 12:50
  • 1
    no, we are passing an anonymous function to `.find()` and `item` is the first *parameter* of that function. – QoP Oct 13 '16 at 12:54