Search code examples
angularngrxngrx-storengrx-effects

Empty object is getting passed to post method while using NgRx


I'm new to NgRx and I'm trying to call the post method of my service using NgRx. I'm passing in a booking object but I get an error saying an empty object was passed. In the Redux DevTools I can see the object in the Action section. I notice there's a new property called 'type' in my object as well.

Error:

{
    "": [
        "A non-empty request body is required."
    ],
    "booking": [
        "The booking field is required."
    ]
}

booking.action.ts

export const addBooking = createAction(
    '[Booking API] Add booking',
    props<{ booking: Booking}>()
)

export const addBookingSuccess = createAction(
    '[Booking API] Add booking success',
    props<{ booking: Booking}>()
);

booking.reducer.ts

export const bookingReducer = createReducer(
    //Supply initial state
    initialState,
    //Trigger loading bookings
    on(loadBookings, (state) => ({ ...state, status: 'loading' as const })),
    on(loadBookingsSuccess, (state, { bookings }) => ({
        ...state,
        bookings: bookings,
        error: '',
        status: 'success' as const,
    })),
    on(addBooking, (state) => ({ ...state, status: 'loading' as const })),
    on(addBookingSuccess, (state, { booking }) => (
        {
        ...state,
        bookings: [...state.bookings, booking],
        error: '',
        status: 'success' as const,
    }))
)

booking.effects.ts

addBooking$ = createEffect(() =>
        this.actions$.pipe(
            ofType(BookingActions.addBooking),
            switchMap((action) =>
                from(this.bookingService.postBooking(action.booking)).pipe(
                    map((booking) =>                     
                        BookingActions.addBookingSuccess({ booking: booking}))
                )
            )
        )
    )

booking.selector.ts

export const featureKey = 'bookings';

export const selectFeature = createFeatureSelector<AppState>(featureKey);

export const selectFeatureLoadBookings = createSelector(
  selectFeature,
  (state: AppState) => state.bookings
);

export const selectFeatureAddBookings = createSelector(
  selectFeature,
  (state: AppState) => state.bookings
)

Calling dispatch

this.store.dispatch(addBooking(this.newBooking));

Redux dev tools

enter image description here


Solution

  • The syntax is wrong when you call:

    this.store.dispatch(addBooking(this.newBooking));
    
        "The booking field is required."
    

    The action of addBooking is defined as follows :

    export const addBookingSuccess = createAction(
        '[Booking API] Add booking success',
        props<{ booking: Booking}>()
    );
    

    There is an object : {booking: Booking};

    So, dispatch the corresponding actions using the store.dispatch() method like that:

    this.store.dispatch(addBooking({booking: this.newBooking}));