0

I am having a hard time to figure this out.

I am using redux in my app and want to return a completely new object from my switch statement. Lets say we have an initial state and then when a componentWillMount we make an ajax request and we want to override the initial state with these new values. The keys of the object from the ajax request are the SAME as the initial state object. However, the values obviously changed. What is the most efficient and clean way to return a new javascript object?

const INITIAL_STATE = {
  name: "",
  email: "",
  phoneNumber: "",
  uid: "",
  photoURL: "",
  address: {
    city: "",
    country: "",
    street: "",
    details: ""
  },
  pastOffers: [],
  memberSince: "",
  gender: "",
  birthday: "",
  description: "",
  worker: false
};

export default (state = INITIAL_STATE, action) => {

  switch (action.type) {
    case FETCH_USER_SUCCESS:
      return { ...state, HOW DO I INSERT ACTION.PAYLOAD HERE };

    default:
      return state;
  }
};

I was thinking of using lodash and doing a _.each() and then passing an object to the reducer with (prop, value) and then doing:

return { ...state, [action.payload.prop]: action.payload.value }

but that seems a little too much. Is there any simpler way?

16
  • Object.assign({...},initial_state); Commented Jul 23, 2017 at 11:38
  • @Jonasw Can you elaborate? Commented Jul 23, 2017 at 11:39
  • 1
    or couldnt you do {...state,...actions.payload} ? Commented Jul 23, 2017 at 11:40
  • 1
    If it's the same structure, just return the payload. Commented Jul 23, 2017 at 11:41
  • 1
    I've missed that in your previous comment { ...state, action.payload } - this is an error. This - { ...state, ...action.payload } spreads them both into a new object. Commented Jul 23, 2017 at 11:55

3 Answers 3

2

Either copy both objects into a new one:

{...state,...actions.payload}

Object.assign({},state,actions.payload);

or use inheritance maybe:

Object.create(state,actions.payload);
Sign up to request clarification or add additional context in comments.

Comments

0

take a look at this example with user service:

const initialState = {
    fetching: false,
    fetched: false,
    users: [],
    error: null,
};

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case "FETCH_USERS_PENDING":
            {
                return { ...state,
                    fetching: true
                }
                break;
            }
        case "FETCH_USERS_REJECTED":
            {
                return { ...state,
                    fetching: false,
                    error: action.payload
                }
                break;
            }
        case "FETCH_USERS_FULFILLED":
            {
                return {
                    ...state,
                    fetching: false,
                    fetched: true,
                    users: action.payload,
                }
                break;
            }
    }
    return state
}
store.dispatch({
    type: "FETCH_USERS",
    payload: /* user service */
})

Comments

0

JavaScript tries to be clever when manipulating objects.

If you have a CONST and you want to return a new instance every time. Then I assign the object as a string which you never manipulate. When you want a new instance of this "object" then you can create the object there and then.

const INITIAL_STATE = '{ "name": "", "email": "", "phoneNumber" : "", "uid" : "", "photoURL" : "", "address": { "city": "", "country": "", "street": "", "details" : "" }, "pastOffers" : [], "memberSince": "", "gender": "", "birthday": "", "description": "","worker": false };

Now you have a string object with your defined schema. Returning new instances is as simple as

function getNewInstance() {
  var newInstance = JSON.parse(INITIAL_STATE);
  newInstance["name"] = "Joe Bloggs";
  newInstance["email"] = "Joe@bloggs";
  return newInstance;
}

Alternatively you just declare the object there and then and return the new instance prepopulated.

function getNewInstance(name, email, phoneNumber) {
    return {
      "name": name,
      "email": email,
      "phoneNumber": phoneNumber,
      "uid": "",
      "photoURL": "",
      "address": {
        "city": "",
        "country": "",
        "street": "",
        "details": ""
      },
      "pastOffers": [],
      "memberSince": "",
      "gender": "",
      "birthday": "",
      "description": "",
      "worker": false
    };
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.