Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: Cannot read property 'map' of undefined using ReactJs

I'm getting a "TypeError: Cannot read property 'map' of undefined". Not sure where I'm going wrong on this. I'm still pretty new when it comes to React so I don't know if I am missing something or not. It's giving me the error when I'm trying to call this.props.meals.map

export class Dashboard extends React.Component {
  componentDidMount() {
    this.props.dispatch(fetchProtectedData());
    this.props.dispatch(retrieveDailyLogs())
    .then(results => {
        return this.props.dispatch(getDailyLogs(results));
    })
}

getId(id) {
   console.log('test');
   this.props.dispatch(removeDay(id))
   this.props.dispatch(retrieveDailyLogs())
  .then(results => {
    return this.props.dispatch(getDailyLogs(results));
});
}


render() {
    const dailyLogs = this.props.meals.map((day, index) => 
    <li className="card" key={index}>
        <Card handleClick={(id) => this.getId(id)} {...day} />
    </li>
    )
    return (
        <section className="dashboard-container">
            <h1>Dashboard</h1>
            <Link className="log-day-btn" to="/dailylogs">Log Meals</Link>
            <ul className="meal-list">
            {dailyLogs}
            </ul>
        </section>
    );
}
}

const mapStateToProps = state => ({
  meals: state.dailyLogsReducer.dailyLogs
});

export default requiresLogin()(connect(mapStateToProps)(Dashboard));

Here is my reducer just in case this might help

import {ADD_DAY, GET_DAILYLOGS, DELETE_DAY} from '../actions/dailyLogs';

const initialState = {
 dailyLogs: [{
    date: null,
    meal1: null,
    meal2: null,
    meal3: null,
    snack: null,
    totalCalories: null,
}]
};

export default function reducer(state = initialState, action) {
 if (action.type === ADD_DAY) {
    return Object.assign({}, state, {
        dailyLogs: [...state.dailyLogs, {
            date: action.date,
            meal1: action.meal1,
            meal2: action.meal2,
            meal3: action.meal3,
            snack: action.snack,
            totalCalories: action.totalCalories
        }]
    });
}
else if(action.type === GET_DAILYLOGS) {
    return Object.assign({}, state, {
            dailyLogs: action.dailyLogs.dailyLogs
    })
}
else if(action.type === DELETE_DAY) {
    return 'STATE';
}
return state;
}

Here is my combineReducer. It is in my store.js

combineReducers({
    form: formReducer,
    auth: authReducer,
    protectedData: protectedDataReducer,
    dailyLogsReducer
}),
like image 541
D.Graves Avatar asked Dec 23 '22 04:12

D.Graves


1 Answers

The render method can run before componentDidMount does. If this.props.meals is not yet defined by the time the render method runs, your component will throw the error you're seeing.

You can check against its presence before mapping through the object with

this.props.meals && this.props.meals.map( // your code here )
like image 101
David Gonzalez Avatar answered Jan 18 '23 22:01

David Gonzalez