Reputation: 2560
I am having a strange issue using object spread. Here is my code:
const AuthenticationReducer = (state = {
authenticationObj: {
"isAuthenticating": true, "isAuthentic": false, "subscriberId": "NA", "username": "NA",
"firstName": "NA", "lastName": "NA", "enabled": "1", "email": "NA", isAuthorized: false
}, lastPasswordCheckStatus: undefined, isSuccessfulChangePassword:undefined,loginUserCheckStatus: undefined, createUserCheckstatus: undefined,
confirmUserCheckstatus: undefined, isSuccessfulChangeEmail:undefined, userContactInfo: {
country: undefined,
address1:undefined,
address2:undefined,
city:undefined,
postalCode:undefined,
phoneNumber: undefined
}
}, action) => {
switch (action.type) {
case SET_USER_CONTACT_INFO:
console.log(JSON.stringify(state));
state = {
...state,
authenticationObj: {
...state.authenticationObj, userContactInfo: action.payload.userContactInfo
}
};
console.log(JSON.stringify(state));
console.log(action.payload.userContactInfo);
}
return state;
};
export default AuthenticationReducer;
Before SET_USER_CONTACT_INFO call the state is as follows:
{
"authenticationObj": {
"isAuthenticating": false,
"isAuthentic": true,
"subscriberId": 4424,
"username": "cccc",
"firstName": "null",
"lastName": "null",
"email": "cccc",
"isAuthorized": true
},
"userContactInfo": {}
}
As you see "userContactInfo": {} is empty object which make sense now as soon as SET_USER_CONTACT_INFO request is dispatched I get:
{
"authenticationObj": {
"isAuthenticating": false,
"isAuthentic": true,
"subscriberId": 4424,
"username": "vvvv",
"firstName": "null",
"lastName": "null",
"email": "vvv",
"isAuthorized": true,
"userContactInfo": {
"country": "Canada",
"address1": "ssss",
"address2": "sss",
"city": "ssss",
"postalCode": "ss",
"phoneNumber": "sss"
}
},
"userContactInfo": {}
}
I get both userContactInfo one empty and one with info. It is really strange I expect the userContactInfo with new info is replaced with the empty one. what is wrong with my code? any help?
Upvotes: 0
Views: 47
Reputation: 1627
This: state = { ...state, authenticationObj: { ...state.authenticationObj, userContactInfo: action.payload.userContactInfo } };
Should be: state = { ...state, userContactInfo: { ...state.userContactInfo action.payload.userContactInfo } };
You have told the script to insert the action.payload.userContactInfo into the authenticationObj, whereas it should placed as a sibling to it.
Sorry it's short I've wrote this on my phone.
Upvotes: 1
Reputation: 816760
I expect the userContactInfo with new info is replaced with the empty one.
The two userContactInfo
are on different levels. One is at the top level, next to authenticationObj
, the other is in the value of authenticationObj
itself, which you easily see by looking at the indentation. Besides, an object cannot have two properties with the same name.
{
"authenticationObj": {
"isAuthenticating": false,
"isAuthentic": true,
"subscriberId": 4424,
"username": "vvvv",
"firstName": "null",
"lastName": "null",
"email": "vvv",
"isAuthorized": true,
"userContactInfo": { // <root>.authenticationObj.userContactInfo
"country": "Canada",
"address1": "ssss",
"address2": "sss",
"city": "ssss",
"postalCode": "ss",
"phoneNumber": "sss"
}
},
"userContactInfo": {} // <root>.userContactInfo
}
I.e. you are merging the object on the wrong level. Seems what you want is
state = {
...state,
userContactInfo: action.payload.userContactInfo
};
Upvotes: 3