I am trying to update the user
object’s blockedUsers
array, while keeping other data not changed. user
object can have blockedUsers
array or not, it is not certain. In slice I have:
reducers: { CHANGE_USER: (state, action) => {
state.user.push(action.payload)
},
}
And in component, I am trying to update this way:
dispatch(CHANGE_USER({blockedUsers: [...user?.blockedUsers, selectedUser] }))
where selectedUser is an object: {id: "xxxx", name: "yyyy"}
. But error comes:
Possible unhandled promise rejection (id:2).
TypeError: Invalid attempt to spread non-iterable instance. In order to be iterable, non-array objects must have a [Symbol.iterator()] method.
Also, when I try this way:
dispatch(CHANGE_USER(blockedUsers?.selectedUser))
then, another Error:
ReferenceError: Property 'blockedUsers' doesn't exist
How can I solve this?
3
Answers
Try this i think this is happening cause you’re directly spreading object in a array.
dispatch(CHANGE_USER({blockedUsers: [{…user?.blockedUsers, selectedUser}] }))
The error you are getting is because user?.blockedUsers might be undefined, and spreading an undefined value produces the error you are seeing.
Solution
You safely update the blockedUsers array by checking first whether it exists. If it is undefined, you initialize it as an empty array, and then you can spread it.
Here’s how you can handle that:
1. Check if blockedUsers exists: Use the || [] fallback, to make sure you’re always spreading an array and never undefined
2. Update reducer logic: Instead of using state.user.push(), update state accordingly, merging the existing state with the new values.
Updated Reducer:
Keep in mind that your reducer updates the user object accordingly, merging the old values with the new one.
Do that this way:
Dispatching the Update:
Now, when dispatching, ensure that blockedUsers exists or falls back to an empty array:
Explanation:
user?.blockedUsers || []: This checks whether blockedUsers exists; if not, it defaults to an empty array ([]).
state.user = { .state.user, .action.payload }: In this way, you make sure you are updating only the properties passed in the payload-for example, blockedUsers-without overwriting the whole user object.
This would avoid the "Invalid attempt to spread non-iterable instance" error and update your blockedUsers array correctly.
If users is an object with a property blockedUsers, to update it you should be doing the following within the reducer
This takes the existing user states and assures that it remains the same, and for the blockedUsers it will keep all the users that are already within the array and add whatever is in the payload.
The payload should now be something like this for this to work as expected
usersToBlock has to be an array, let me know if this causes any new errors.