0

I'm learning React-Redux and have come to an issue when trying to render out a side navigation "sub section" item from a nested object.

Here is the component:

import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';

class SideNav extends Component {  
  render() {
    return (
    <div className="sidenav-cont">
        <ul className="top-level-menu">
              {
  this.props.reducerSidenav.map((menuItem) => {
    return (
      <li key={menuItem.catId}>
        <a href="#">{menuItem.parentCat}</a>
        <ul className="bottom-level-menu">
          {  
            this.props.reducerSidenav.subCats.map((subMenuItem) => {
              <li key={subMenuItem.subCatId}><a href="#">{subMenuItem.subCatLabel}</a></li>
            })
          }
        </ul>
      </li>
      )
    })
  }
        </ul>
    </div>
    )
  }
}



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

export default connect(mapStateToProps)(SideNav);

if I remove the second nested <ul> with the className "bottom-level-menu" then the app renders out my "parent section" list item no problem. But it's when I attempt to re-create the same function but for a nested objected that I get errors. Here is my reducer with the sidenav menu object:

export default function(){
    return [
            {
            catId:"parMenu1",
            parentCat:"Bass",
            subCats:[
                {
                    subCatId:"subMenu1",
                    subCatLabel:"base1"
                },
                {
                    subCatId:"subMenu2",
                    subCatLabel:"base2"
                },
                {
                    subCatId:"subMenu3",
                    subCatLabel:"base3"
                },
                {
                    subCatId:"subMenu4",
                    subCatLabel:"base4"
                }
            ]
        },
        {
            catId:"parMenu2",
            parentCat:"treb",
            subCats:[
                {
                    subCatId:"subMenu1",
                    subCatLabel:"treb1"
                },
                {
                    subCatId:"subMenu2",
                    subCatLabel:"treb2"
                },
                {
                    subCatId:"subMenu3",
                    subCatLabel:"treb3"
                },
                {
                    subCatId:"subMenu4",
                    subCatLabel:"treb4"
                }
            ]
        },
        {
            catId:"parMenu3",
            parentCat:"drums",
            subCats:[
                {
                    subCatId:"subMenu1",
                    subCatLabel:"drums1"
                },
                {
                    subCatId:"subMenu2",
                    subCatLabel:"drums2"
                },
                {
                    subCatId:"subMenu3",
                    subCatLabel:"drums3"
                },
                {
                    subCatId:"subMenu4",
                    subCatLabel:"drums4"
                }
            ]
        },
    ]
}

As you can see the nested object to be used for the sub navigation items is titled subCats. I would have thought that I could access the object within another object by referring to the sidenav reducer state like so: this.props.reducerSidenav.subCats.map((subMenuItem) => {... much like I did for the parent categories but I'm getting the "Cannot read property 'map' of undefined" error in console. Where have I gone wrong?

Mr Lister
  • 45,515
  • 15
  • 108
  • 150

3 Answers3

2

There is a bug in your code.

this.props.reducerSidenav.subCats.map((subMenuItem) => {
                                <li key={subMenuItem.subCatId}><a href="#">{subMenuItem.subCatLabel}</a></li>
                            })

reducerSidenav is a table, probably you wanted to have something like this

menuItem.subCats.map((subMenuItem) => {
                                <li key={subMenuItem.subCatId}><a href="#">{subMenuItem.subCatLabel}</a></li>
                            })
niba
  • 2,821
  • 1
  • 19
  • 23
  • I tried replacing with menuItem.subCats.map. It doesn't render an error anymore but it's not rendering out any list items. Also I was a little confused in your answer as to where to use this.props.reducerSidenav[index] –  Oct 12 '16 at 21:01
  • sorry, I wanted to point out how to pick an element from a table by using `this.props.reducerSidenav[index]`, I removed that note from my original answer. Regarding your problem I don't know why there is nothing rendered, maybe add `console.log(menuItem.subCats)` to check what you get from store/state – niba Oct 12 '16 at 21:57
  • Just did and it returns all the objects. I took a screenshot of the console if that helps: https://s18.postimg.org/fa0yqq3c9/Untitled.png –  Oct 12 '16 at 22:08
  • ok, i know, you dont have a return there `return
  • {subMenuItem.subCatLabel}`
  • – niba Oct 12 '16 at 22:15
  • That was it, thank you. Just curious do you always have to use return after a .map function? –  Oct 12 '16 at 22:17
  • 1
    you dont need to, there are cases when you dont need to write `return` keyword, here you have more about this topic http://stackoverflow.com/questions/28889450/when-should-i-use-return-in-es6-arrow-functions – niba Oct 12 '16 at 22:20