Reputation: 109
I am a novice at redux and i am trying to incorporate it in my code so the state can be managed more easily. I am trying to map through an array in my state but it is throwing the error below:
Uncaught TypeError: Cannot read property 'map' of undefined
this is the reducer for redux
const initialState = {
workoutlist: [
{
id: uuid.v4(),
name: 'Leg Day',
date: '08-09-2019',
duration: "60",
exerciselist: [
{
id: uuid.v4(),
exerciseName: 'Squats',
numberOfSets: "3",
reps: "12",
weight: "135",
},
{
id: uuid.v4(),
exerciseName: 'Leg press',
numberOfSets: "3",
reps: "10",
weight: "150",
},
{
id: uuid.v4(),
exerciseName: 'Lunges',
numberOfSets: "4",
reps: "12",
weight: "0",
},
],
selected: false,
},
{
id: uuid.v4(),
name: 'Running',
date: '08-11-2019',
duration: "40",
exerciselist: [],
selected: false,
},
],
disabled: true,
page: 1,
}
const workoutList = (state = initialState, action) => {
switch(action.type) {
// Returns whether the panel is selected or not
// and enables Start Workout button if only 1 is selected
case 'SELECT_PANEL':
state = {
workoutlist: state.workoutlist.map(workout => {
if (workout.id === action.id) {
workout.selected = !workout.selected
}
return workout;
})
}
var count = 0;
state.workoutlist.map((workout) => {
if (workout.selected === true) {
count = count + 1;
}
return count;
})
if (count !== 1) {
state = {
...state,
disabled: true
}
} else {
state = {
...state,
disabled: false
}
}
return state;
default:
return state;
}
}
this is the component that where the error is being thrown.
export default function WorkoutItem() {
const handleSelectedPanel = useSelector(state => state.workoutList);
const dispatch = useDispatch();
const { name, date, duration, exerciselist } = handleSelectedPanel;
return (
<ExpansionPanel style={styles.panel} onChange={() => dispatch(selectPanel())}>
<ExpansionPanelSummary>
<Typography variant="button" style={styles.header}>
{name}
</Typography>
<Typography variant="button" style={styles.header}>
{date}
</Typography>
<Typography align="right" style={styles.header}>
~{duration} mins
</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Table size="medium" style={styles.table}>
<TableHead>
<TableRow>
<TableCell padding="none" >Name</TableCell>
<TableCell padding="none" align="right"># of sets</TableCell>
<TableCell padding="none" align="right">average reps</TableCell>
<TableCell padding="none" align="right">weight</TableCell>
</TableRow>
</TableHead>
<TableBody>
{exerciselist.map((exercise) => (
<ExerciseList
key={exercise.id}
exercise={exercise}
/>
))}
</TableBody>
</Table>
<ExpansionPanelActions disableSpacing style={styles.actionButton}>
<EditWorkoutItem
workout={this.props.workout}
handleEditChange={this.props.handleEditChange}
/>
</ExpansionPanelActions>
</ExpansionPanelDetails>
</ExpansionPanel>
)
}
It is supposed to show a list of panels that can be expanded to show the contents but it throws an error saying the exerciselist is undefined in my state apparently.
Any help would be greatly appreciated!
Upvotes: 0
Views: 357
Reputation: 3756
Do you want to access the first item or workoutList
?. From your code handleSelectedPanel
seams to be an array not an object. Is your destructuring correct?. Where is your useSelector
?. What does console.log(handleSelectedPanel)
gives you? Try
const { name, date, duration, exerciselist } = handleSelectedPanel[0];
or
const handleSelectedPanel = useSelector(state => state.workoutList[0]);
Upvotes: 1