#NgRx Signal store - rxMethod() not triggering after error

2 messages · Page 1 of 1 (latest)

west ibex
#

Hello, i'm having a really hard time trying to understand why the rxMethod of my store doesn't trigger again after getting an error from an api.

STORE:

export const UsersStore = signalStore(
    { providedIn: 'root' },
    withState(initialState),
    withMethods((store, usersService = inject(UserService), alertService = inject(AlertService), router = inject(Router)) => ({
      addUser: rxMethod<UserRequest>(pipe(
        switchMap((user) => usersService.createUser(user)),
          tapResponse({
            next: (createdUser) => {
              patchState(store, (state) => ({ users: [...state.users, createdUser] }));
              alertService.getSuccessToast('Exito!').fire();
              router.navigate(['users', 'dashboard']);
            },
            error: (error: HttpErrorResponse) => {
              alertService.getErrorAlert(error.message).fire()
            }
          })
      ))
})),
);

Basically, if i get an error, the alertService will tell the user the error (the error i'm testing simply notifies that the name entered already exists). Then, if the user tries to correct the wrong input and press submit again, the rxMethod doesn't trigger anymore, and i don't understand why :/

The component where i call simply does this:

public onSubmit() {
  console.log("calling store.addUser!");
  this.userStore.addUser(this.user()!);
}

The console.log() appears correctly whenever i press submit, but the store doesn't make the API request.

Also, is it correct to handle the api response like success or error with alerts directly in the store? Or should i handle that in the component and pass the request status to the component? (pending, success, error)

tall imp
#

I'm not entirely sure what is going on, but an error in an observable chain exits the observable. The way to prevent it is to catch the error.

Maybe try putting this

switchMap((user) => usersService.createUser(user)).pipe(
          tapResponse({
            next: (createdUser) => {
              patchState(store, (state) => ({ users: [...state.users, createdUser] }));
              alertService.getSuccessToast('Exito!').fire();
              router.navigate(['users', 'dashboard']);
            },
            error: (error: HttpErrorResponse) => {
              alertService.getErrorAlert(error.message).fire()
            }
          }),
          catchError(error => of(error))
      )
      ))

to catch the error in the switchMap block and not have it terminate the observable