Home > Back-end >  Problems achieving required result of using the spread (...) operator with state object
Problems achieving required result of using the spread (...) operator with state object

Time:02-28

I have a pimRegistration state initilization as shown in the chrome redux-devtools screen capture below. The nesting being referenced is pimRegistration (state.domain.patient):

enter image description here

I updated the patient.name object with the following spread operator statement:

        store.update((state) => ({
            ...state, ...patientPath,
            ...{  [property]: value },

        }))

...where property is the 'name' property of the patient object with 'value'. After the update the following screenshot shows the new state:

New updated state - yellow colour in screenshot

Note that the original patient object (purple in screenshot) is updated with the name object, duplicated and placed at the root of the state (yellow in screenshot).

I would like to placed the updated patient object to replace the pimRegistration(state).domain.patient object, NOT create a new patient object at the root of the state.

How can I achieve this by using the spread operator in the state update function as shown below:

        store.update((state) => ({
            ...state, 
            ...patientPath, // state.domain.patient
            ...{  [property]: value },

        }))

I have tried my different combinations without achieving the desired result.

The complete update function is shown below:

update(property: string, path: string, value: any) {
        const paths: string[] = path.split('.')

        const pathReducer = (state: IRegistrationState, path_: string) => {
            if (paths.length <= 0) {
                return state.domain
            }
            return state[path_]
        }

    const domainPath = state.domain
        let patientPath, nokPath, referrerPath



        if (path.includes('patient')) {
            patientPath = paths.reduce(pathReducer, state)
        }

    if (path.includes('nok')) {
      nokPath = paths.reduce(pathReducer, state)
    }

    if (path.includes('referrer')) {
      referrerPath = paths.reduce(pathReducer, state)
    }

        store.update((state) => ({
            ...state, ...patientPath,
            ...{  [property]: value },

        }))
    }
}

The function is invoked with the following statement in the UI component (angular2)

        if (this.path.includes('patient')) {
          this._repo.update( 'name', 'domain.patient', this.name)
            }

Thanks

CodePudding user response:

Deep updates to a store can be tricky. In your function you seem to be spreading the updates at the root rather than at the level you want the update at. This answer here outlines the usual practice to update the state. In short, something like

const newState = {
  ...state,
  domain: {
    ...state.domain,
    patient: {
      ...state.domain.patient,
      [property]: value
    }
  }
}

Dynamically passing a path and updating this state can be… cumbersome. There are libraries that can help you do it such as immer, but you can possibly hack your way around with normal JS/TS.

  • Related