0
votes

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?

3

3 Answers

2
votes

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>
                            })
0
votes

Quote your keys?

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"
            }
        ]
    },
]

}

0
votes

I think the "this" keyword inside your first map() function does not reference what you think it does. You need to bind "this" to the map() function to access the props in the outer object:

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>
        )
    }.bind(this))
 }