Someone Special
Someone Special

Reputation: 13588

Redux Reducer - Adding new data to nested state

I've saved the following json file in the client state in the reducer. Now as I add new Notes, via ajax, I'm calling the NEW_NOTE_SUCCESS reducer, which is suppose to add the new note to existing note array.

export default function clientProfile(state={}, action) {

    switch(action.type) {


        case NEW_NOTE_SUCCESS:
            console.log(action.payload);
            return { ...state, notes: [...state.notes, action.payload] }

        default:
            return state;
    }

}

However, after I did the above, this.props.client.notes will only have the new note I added, but not the old ones.

What should i do to "push" the new note into the array, so I do not need to resend the notes json file everytime I add a new note.

PS: action.payload contains the following json.

{
            "noteId": "10000000",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510316194",
            "note": "ADDED A NEW NOTE. NEED TO ADD TO STATE"
        }

this is the original json file on the intial load.

{
    "customerId": "34",
    "agentId": "1",
    "createdDate": "1510223892",
    "firstname": "John",
    "lastname": "Doe",
    "mobile": "123456789",
    "address": "Something email here",
    "notes": {
        "0": {
            "noteId": "1",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510316194",
            "note": "add something"
        },
        "1": {
            "noteId": "2",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510316527",
            "note": "add something"
        },
        "2": {
            "noteId": "3",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510317177",
            "note": "add new thing"
        },
        "3": {
            "noteId": "4",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510318448",
            "note": "something"
        },
        "4": {
            "noteId": "5",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510318476",
            "note": "this would be note number 5, lets see whether we can get something from this."
        }
    }
}

Updated: Reducer Codes - Object instead of array.

case NEW_NOTE_COMPLETE:
    return { ...state, notes: {...state.notes, action.payload.noteId: action.payload} }

Upvotes: 1

Views: 5647

Answers (1)

Sagiv b.g
Sagiv b.g

Reputation: 31024

It seems to me that your data structure got mixed.
In your json file the note key is an object but inside your reducer you are handling it as an array.
So this line:

return { ...state, notes: [...state.notes, action.payload] }

Should be more like this (i just hard-coded the key 5 you should make it dynamic calculated somehow):

return {...state, notes: {...state.notes, "5": action.payload}}

Edit
As a followup to your comment:

but how do u make it dynamically calculated, it doesn't seems to let me use a variable

lets say you want to use noteId as your key, then you can use the computed property names of es2015

[action.payload.noteId]: action.payload

I updated the snippet to illustrate.

Here is small running example:

const jsonObj = {
  "customerId": "34",
  "agentId": "1",
  "createdDate": "1510223892",
  "firstname": "John",
  "lastname": "Doe",
  "mobile": "123456789",
  "address": "Something email here",
  "notes": {
    "0": {
      "noteId": "1",
      "customerId": "34",
      "createdBy": "1",
      "created": "1510316194",
      "note": "add something"
    },
    "1": {
      "noteId": "2",
      "customerId": "34",
      "createdBy": "1",
      "created": "1510316527",
      "note": "add something"
    },
    "2": {
      "noteId": "3",
      "customerId": "34",
      "createdBy": "1",
      "created": "1510317177",
      "note": "add new thing"
    },
    "3": {
      "noteId": "4",
      "customerId": "34",
      "createdBy": "1",
      "created": "1510318448",
      "note": "something"
    },
    "4": {
      "noteId": "5",
      "customerId": "34",
      "createdBy": "1",
      "created": "1510318476",
      "note": "this would be note number 5, lets see whether we can get something from this."
    }
  }
}

const newNote = {
  "noteId": "10000000",
  "customerId": "34",
  "createdBy": "1",
  "created": "1510316194",
  "note": "ADDED A NEW NOTE. NEED TO ADD TO STATE"
}
const action = {
  type: 'NEW_NOTE_SUCCESS',
  payload: newNote
};

function clientProfile(state = {}, action) {
  switch (action.type) {
    case 'NEW_NOTE_SUCCESS':
      {
        return {...state, notes: {...state.notes, [action.payload.noteId]: action.payload
          }
        }
      }

    default:
      return state;
  }
}


let reducer = clientProfile(jsonObj, {type: ''});
console.log("before the change",reducer.notes)
reducer = clientProfile(jsonObj, action);
console.log("after the change",reducer.notes)

Upvotes: 2

Related Questions