Reputation: 127
I'm working on implementing beautiful-dnd in my react project.
I have the following data:
const initialData = {
users: {
'user-1': { id: 'user-1', name: 'John'},
'user-2': { id: 'user-2', name: 'Patrick'},
'user-3': { id: 'user-3', name: 'Malorie'},
'user-4': { id: 'user-4', name: 'Eric'},
'user-5': { id: 'user-5', name: 'Bob'},
'user-6': { id: 'user-6', name: 'Blob'}
},
areas: {
'area-0': {
id: 'area-0',
title: 'Main Area',
userIds: ['user-1', 'user-2', 'user-3', 'user-4', 'user-5', 'user-6']
},
'area-1': {
id: 'area-1',
title: 'Area 1',
userIds: []
},
'area-2': {
id: 'area-2',
title: 'Area 2',
userIds: []
}
},
areaOrder: ['area-0', 'area-1', 'area-2'],
}
In the reducer, I try to remove one of the users this way:
case REMOVE_USER_ACTION:
return {
...state,
users: [ ...state.users.filter(user => user !== action.id) ]
}
I'm getting this error:
TypeError: e.users.filter is not a function or its return value is not iterable
I searched for this error, but I'm unable to find a comparable scenario and how to fix this issue.
Upvotes: 1
Views: 52
Reputation: 14228
TypeError: e.users.filter is not a function or its return value is not iterable
It means that users
is not an array, it's object
instead.
So you can get the filtered users in this way:
const users = {'user-1':{id:'user-1',name:'John'},'user-2':{id:'user-2',name:'Patrick'},'user-3':{id:'user-3',name:'Malorie'},'user-4':{id:'user-4',name:'Eric'},'user-5':{id:'user-5',name:'Bob'},'user-6':{id:'user-6',name:'Blob'}};
const actionId = "user-1";
const filteredUsers = Object.entries(users).filter(([key, value]) => value.id != actionId);
console.log(Object.fromEntries(filteredUsers));
As a result, your REMOVE_USER_ACTION
looks like
case REMOVE_USER_ACTION:
return {
...state,
users: filteredUsers
}
However, you should change users
type from object
to array
in terms of performance, meaningful name & clean code.
const users = [{ id: 'user-1', name: 'John'},
{ id: 'user-2', name: 'Patrick'},
{ id: 'user-3', name: 'Malorie'},
{ id: 'user-4', name: 'Eric'},
{ id: 'user-5', name: 'Bob'},
{ id: 'user-6', name: 'Blob'}
];
const actionId = "user-1";
const filteredUsers = users.filter(item => item.id != actionId);
console.log(filteredUsers);
Upvotes: 2
Reputation: 18183
users
is an object, not an array, so you can't iterate over it
Here is a possible solution using Object.entries
case REMOVE_USER_ACTION:
return {
...state,
users: Object.entries(state.users).reduce((acc, [key, value]) => {
if (key !== action.id) {
acc[key] = value;
}
return acc;
}, {})
}
Upvotes: 1
Reputation: 506
Can't filter the state.users
if your data is an object. It's either you change the initialData shape or if it's really like that, then you'd have to do some way to delete a key from your object.
case REMOVE_USER_ACTION:
const users = { ...state.users };
delete users[action.id];
return {
...state,
users,
}
Upvotes: 1