Search code examples
angularnrwlnrwl-nx

Angular Nrwl Nx Data Persistence with non-class Actions


Is it possible to use non-class-based actions with Nx Data Persistence? I could not find anything in the docs. This here is what I tried so far:

run: (action, state) => {
      const booking: Booking = action.booking;
      return this.httpClient.post<FirebasePostResponse>('https://foo/bar.json', booking).pipe(
        map((res, err) => {
          return bookingsAddOneSuccess({booking});
        })
      );
    },

which is giving me a type mismatch error. I guess a workaround would be to use @Effect({dispatch: false}) and dispatch from the run method yourself without returning anything. But perhaps there is a better way, without misusing Effects?


Solution

  • NgRx now features action creators:

    export const addOne('[Bookings] Add One', props<{ booking: BookingsEntity }>());
    
    export const addOneSuccess('[Bookings] Add One Success', props<{ booking: BookingsEntity }>());
    

    Which work fine with Nx's Data Persistence functions:

    addOne = createEffect(() =>
      this.actions.pipe(
        ofType(BookingsActions.addOne),
        pessimisticUpdate({
          // provides an action
          run: ({ booking }) => {
            // update the backend first, then dispatch an action
            // that will update the client side
            return this.httpClient.post<FirebasePostResponse>(
              'https://foo/bar.json',
              booking
            ).pipe(
              map((res, err) => {
                return BookingsActions.bookingsAddOneSuccess({ booking });
              })
            );
          },
          onError: ({ booking }, error) => {
            // we don't need to undo the changes on the client side.
            // we can dispatch an error, or simply log the error here and return `null`
            return null;
          },
        })
      )
    );