0

I have one value from the server. It contains object with the same key as in my state object. Key value of that object is an array with one item. To handle this value in my reducer I need to add this array item to existing object key in my state.

In short:

I have from the server: { TEST: ['item1'] }

My state is: { TEST: ['item2'], TEST2: ['item3'] }

Expected result: { TEST: ['item1', 'item2'], TEST2: ['item3'] }

const handleCreateItemFilter = (state, { payload }) => {
  const { list  } = payload;
  const updatedList = { ...state.regions.list };
  updatedList[Object.keys(list).join()] = [...updatedList[Object.keys(list).join()], Object.values(list).join()];
  return {
    ...state,
    regions: {
      ...state.regions,
      list: updatedList,
    },
    selectedFilter: {
      ...state.selectedFilter, unassignedCountries: [], regions: Object.keys(list).join(),
    },
  };
};

Currently, I solved it like in the example above: create new updatedList, find appropriate key for my object from the server and assign to my new object array of old key value and new one. But I think it isn't good approach to solve this problem.

David Costa
  • 165
  • 2
  • 10
s_kamianiok
  • 462
  • 7
  • 24
  • Can add the real serve response? and what you really expect? – David Costa Apr 23 '19 at 13:01
  • My expectations is just update my store state using reducer – s_kamianiok Apr 23 '19 at 13:06
  • The wording of your question confused me because keys are strings. Adding an item to an object key didn't make sense to me. And you are writing a reducer, so you are not even adding an item to an array, you are making a new array. And finally --- why don't you think it's a good approach? And have you read https://stackoverflow.com/a/40925668/1563833 – Wyck Apr 23 '19 at 13:11
  • Ok, for me this piece of code `updatedList[Object.keys(list).join()] = [...updatedList[Object.keys(list).join()], Object.values(list).join()];` is very confused. Probally you need to improve this implementation. I`m try make this code work, to try help you. https://jsbin.com/bocudojire/edit?js,console,output – David Costa Apr 23 '19 at 13:18
  • Agreed, this piece of code looks confusing although it works. – s_kamianiok Apr 23 '19 at 13:28

1 Answers1

0

So, I really don't know why you are using object on root state instead of array, but, if I needed to use it I would do some like this:

const response = { TEST: ['item1'] }
const stateInitial = { TEST: ['item2'], TEST2: ['item3']}

const expected = JSON.stringify({ TEST: ['item1', 'item2'], TEST2: ['item3']})

const reducer = (state = stateInitial, { payload }) => {
  return [
    ...Object.entries(payload).map(([k, v]) => (
      typeof stateInitial[k] !== 'undefined' ?
      [ k,[...v, ...stateInitial[k],]] :
      [k, v]
    ))

  ].reduce((obj, [k, v]) => ({ ...obj, [k]: v }), stateInitial)
};


try {
  const output = JSON.stringify(reducer(undefined, { payload: response}))
  if (output != expected) {
    throw `reducer return something different: \n${output} \n\nand expect \n\n${expected}`
  }

  console.log('the test is passed')
} catch (error) {
  console.error(error)
}
David Costa
  • 165
  • 2
  • 10
  • I receive object from the server (my initial state) with regions and each region key contains array of countries. I don't know, It seems to me also not easy to understand what's going on in this code:) – s_kamianiok Apr 23 '19 at 14:04