renakre
renakre

Reputation: 8291

Updating a single value for each item in object in Redux State

I have a list of notifications inside redux state. As you can see below.

There could be more items in the list, and my goal is to set isRead value to true for all items in the list depending on the isDiscussionType value. I am using the following code in the reducer:

case MARKALLASREAD_NOTIFICATIONS_SUCCESS:
    return {
        ...state,
        loading: false,
        notifications:
            Object.keys(state.notifications).map(id => {
                if (state.notifications[id].isDiscussionType == action.payload.isDiscussionType)
                    return { ...state.notifications[id], isRead: true }
                else
                    return { ...state.notifications[id] }
            })

    };

This code results in the following state, where the key is lost (set to 0), and the isRead value is not changed (although the database is updated correctly).

Do you see any problems in the code I shared above?

enter image description here

Upvotes: 0

Views: 76

Answers (2)

Domino987
Domino987

Reputation: 8804

Map returns an array instead of an object. That is why you lose your id, since the 0 is just the index within the array, which is now under notifications. I would move the generation of notifications out of the return to get more flexibility:

case MARKALLASREAD_NOTIFICATIONS_SUCCESS:
    const notifications = { ...state.notifications }
    Object.values(notifications).forEach(notification => {
        if(notification.isDiscussionType === action.payload.isDiscussionType) {
           notifications[notification.id] { ...notification, isRead: true }
        }
    }
    return {
        ...state,
        loading: false,
        notifications
    };

This will return an immutable object with each notification changed, if the isDiscussionType are the same. Because map, filter, reduce return arrays, I would move it out of the return and use forEach.

Hope this helps. Happy coding.

Upvotes: 2

Clarity
Clarity

Reputation: 10873

If your notifications is a list i.e. an array, you shouldn't use Object.keys on it, and go straight with the map:

case MARKALLASREAD_NOTIFICATIONS_SUCCESS:
  return {
    ...state,
    loading: false,
    notifications: state.notifications.map(notification => {
      if (notification.isDiscussionType === action.payload.isDiscussionType) {
        return {
          ...notification,
          isRead: true
        }
      } else {
        return notification;
      }
    })
  };

Upvotes: 0

Related Questions