0

Say I have some initial state like

      const initialState = {
        post: { comments: {
           {0: {id:'1',name:'myname',statusdata: false}},
           {1: {id:'2',name:'yourname',statusdata: true}}, 
      },
   };

And I want add to data as the result of an action but the data I want to add is going to be an array. How do I go about this?

     export default produce((draft, action) => {
      switch (action.type) {
        case UPDATE_NAME:
          draft.posts.comments.name = action.payload;
          break;
        case CHANGE_STATUS:
          draft.posts.comments.statusdata = !action.payload;
          break;
        default:
      }
    }, initialState);

I have this error

Error: [Immer] Immer only supports setting array indices and the 'length' property
bokino12
  • 317
  • 5
  • 13
  • Would you post a sample of `draft.posts.comments` to figure out the data structure? As it looks like you're attempting to set object property, whereas either `posts`, or `comments`, or both appear to be an array. Also, it would be helpful to see `action.payload` structure. – Yevhen Horbunkov Jul 27 '20 at 10:08
  • Here ``post`` is don't array but ``comments`` – bokino12 Jul 27 '20 at 10:16
  • `comments` doesn't seem to be valid object notation (no key for value `{name: ..`). Are you sure about that? And what's the `action.payload` format? – Yevhen Horbunkov Jul 27 '20 at 10:18
  • i have update my question, thank ! – bokino12 Jul 27 '20 at 10:30
  • 1
    `comments` notation is still invalid (no key names for nested objects-values) - it has to be either an object with keys, like `comments: {0: {id: '1'..,} 1: {id: '2'..}}` or it is actually an array, but then square brackets should be used: `comments: [{id: '1'..}, {id: '2'..}]` – Yevhen Horbunkov Jul 27 '20 at 10:34
  • thank! is good now – bokino12 Jul 27 '20 at 10:42

2 Answers2

0

I have made assumptions on the schema of comments and action.payload. Try the following solution.

Object.values(draft.post.comments).map((comment){   
   if(comment.id == action.payload.id){
       const updatedComment = Object.extend({}, comment, {"name": action.payload.name});
       return updatedComment;
   }
   return comment;
})
Vasanth Gopal
  • 1,215
  • 10
  • 11
  • This is assuming that `comments` is an array with square brackets `[..]`. and action.payload is an updated object with `id`, `name` and `statusdata`. Example: `{'id': 1, 'name': 'updatedname', 'statusdata': true}` – Vasanth Gopal Jul 27 '20 at 10:37
  • Please add an example of `action.payload`. How does it look? – Vasanth Gopal Jul 27 '20 at 11:01
0

I'm try

    export default produce((draft, action) => {
      switch (action.type) {
        case CHANGE_STATUS:
          draft.posts.comments[
             draft.posts.comments.findIndex(i => i.id === action.payload)
                    ].statusdata = action.payload;
                return draft;
        default:
      }
    }, initialState);
bokino12
  • 317
  • 5
  • 13