javascriptangularreduxangular-reduxngredux

Updating/ Pushing new data into NgRedux state


I am new to Angular and writing service which I will be using to add new addresses (posting to a REST API).

The saveAddress method call returns a newly created address object on server.

Which I wanted to push into the already existing array of addresses in store. I am trying to do something like:

saveAddress( payload ) {
    this.httpClient.post( this.endpoint, payload).subscribe(
      response => {
        this.ngRedux.select( s => s.addresses ).subscribe( addresses => {
          let data = addresses.data.push( response )

          this.ngRedux.dispatch({ type: ADD_ADDRESS_SUCCESS, payload: data })
        })
      },

      err => {
        this.ngRedux.dispatch({ type: ADD_ADDRESS_ERROR })
      }
    )
  }

How may I do it properly?


Solution

  • You must never alter the Store (state) anywhere else than in a reducer. The reducers receives an action (ADD_ADDRESS_SUCCESS) with its payload ({address: {...}}) and then updates the Store with that information:

    reducer(state = initialState, action) {
      switch (action.type) {
        case ADD_ADDRESS_SUCCESS:
          return Object.assign({}, state, {
            addresses: state.addresses.push(action.payload.address)
          })
        default:
          return state
      }
    } 
    

    Note, that we always make a copy of the state and do not mutate it. To really understand it, please read the documentation for @angular-redux/store.

    For API calls you should use Epics: Think of an Epic as pipeline that transforms an action into one or multiple other actions while handling a side effect. In your case the epic reacts to the ADD_ADDRESS_REQUEST, makes an API call with the payload and then transforms the action into either ADD_ADDRESS_SUCCESS or ADD_ADDRESS_ERROR, depending on the result of the API call. It will never update the state itself but delegate this to the reducer handling ADD_ADDRESS_SUCCESS and ADD_ADDRESS_ERROR respectively.

    Read more about epics in the corresponding @angular-redux/store docs.