1

I have the groups and members object with the following structure in the redux state:

groups :{
    '1683': {
      id: 1683,    
      members: [
        '1',
        '2'
      ],
    },
    '1900': {...}
}

members: {
   '1': {
       name: 'user1'
    }, 
   '2': {
       name:'user2'
    }
}

I have the following code in the reducer to remove a member from groups. The first part where I update the members error inside the group is working fine. But, the code where I want to remove the targeted member from the members object itself is not working. I tried splice but it is not working since members is not an array. I wonder how I can remove the member based on the key-id match. Any suggestions?

    case REMOVE_STUDENT_SUCCESS:
        return {
            ...state,
            groups: {
                ...state.groups,
                [action.payload.groupId]: {
                    ...state.groups[action.payload.groupId],
                    members: state.groups[action.payload.groupId].members.filter(id => id !== action.payload.studentId)
                }
            },

            //NOT WORKING
            //members: state.members.splice(action.payload.studentId, 1)
        };
renakre
  • 8,001
  • 5
  • 46
  • 99
  • possible duplicate https://stackoverflow.com/questions/208105/how-do-i-remove-a-property-from-a-javascript-object – Michael Oct 14 '19 at 07:24
  • You can use the following https://stackoverflow.com/questions/5072136/javascript-filter-for-objects to have filter object and respect the immutability of the data – ocheriaf Oct 14 '19 at 07:29
  • maybe you could `members:delete state.members['1']&&state.members` – Michael Oct 14 '19 at 07:30
  • 1
    If it does not work, you can try : `members : {...state.members, studentId : undefined}` – ocheriaf Oct 14 '19 at 07:36
  • 1
    The problem is that `.splice` *mutates the array*, and you are never allowed to do that with Redux state. You need to generate a new array without the element and return that. Ocheriaf's is one way to do that. – RemcoGerlich Oct 14 '19 at 08:10

3 Answers3

1

I would highly recommend using Immutability-helper library. It makes modifying the immutable state much easier.

Also there is immer library which can help as well.

Robert C
  • 60
  • 2
  • 10
0

I think this is due to type casting, Convert the action payload's studentId value to string. The below will work,

case REMOVE_STUDENT_SUCCESS:
        return {
            ...state,
            groups: {
                ...state.groups,
                [action.payload.groupId]: {
                    ...state.groups[action.payload.groupId],
                    members: state.groups[action.payload.groupId].members.filter(id => id !== action.payload.studentId.toString())
                }
            },

            //NOT WORKING
            //members: state.members.splice(action.payload.studentId, 1)
        };
Gangadhar Gandi
  • 2,162
  • 12
  • 19
0

This solution will work fine:

case REMOVE_STUDENT_SUCCESS: {

    var { members } = this.state;
    for (var property in members) {
      if (members.hasOwnProperty(property)) {
        property == studentId && delete members[property];
      }
    }
        return {
            ...state,
            groups: {
                ...state.groups,
                [action.payload.groupId]: {
                    ...state.groups[action.payload.groupId],
                    members: state.groups[action.payload.groupId].members.filter(id => id !== action.payload.studentId)
                }
            },

            members: members,


        };
    }