Trevor
Trevor

Reputation: 491

Where should the "id" of the new data object be created/assigned?

I'm building a web app using Angular 7, and want to use @ngrx/store and @ngrx/effects.

Disclaimer: I'm new to these technologies.

In a typical client-server application, I would think it makes sense to allow the database to assign the id value, which would then be passed back to the client in the HTTP response.

But given that API calls are supposed to happen in side effects when using NGRX, what's the proper way to update the new object in the state with the id returned in the http response?

My understanding is that side effects are not supposed to manipulate state. That's the whole reason they're called side effects.

What's the proper way to solve this problem?

Upvotes: 1

Views: 753

Answers (1)

timdeschryver
timdeschryver

Reputation: 15507

Some possibilities:

  • You can let the client generate there own ID's.
  • You can only add entities to the store when the server roundtrip is finished. This can be done by returning the whole object back from the server, or to append the id to the entity in an effect:
@Effect()
  save = this.actions.pipe(
    ofType(Foo),
    exhaustMap(({ payload }) =>
      this.service.post(payload).pipe(
        map(
          result =>
            new FooSuccess({
              ...payload,
              id: result,
            })
        ),
        catchError(() => of(new FooFailed()))
      )
    )
  );
  • State manipulations are indeed done via reducers, if you can somehow link the new entity in the store with the returned payload you could update the id via the reducer
@Effect()
  save = this.actions.pipe(
    ofType(Foo),
    exhaustMap(({ payload }) =>
      this.service.post(payload).pipe(
        map(
          result =>
            new FooSuccess({
              reference: payload.reference,
              id: result,
            })
        ),
        catchError(() => of(new FooFailed()))
      )
    )
  );


// and in the reducer

return {
   ...state, 
   // mutate found entity, else just return the entity in the store
   entities: this.state.entities.map(p => p.reference === action.reference ? mutateEntityHere : p)
}

My preferences would be either the first or second option.

Upvotes: 1

Related Questions