1

I am throwing an exception in my service and trying to catch the exception in my effect and return the correct toast on the frontend.

What happens: It looks like i get a success message and then an error is thrown, i see the error in the console but never the "Error" toast on the frontend. I put a breakpoint on the catcherror line in the service. I see the success toast before the breakpoint gets hit.

What should happen: Should show the "Error" toast on the frontend after catching the error.

Can someone see what I am doing wrong?

Service

saveBusiness(business: BusinessModel) {
    return from(this.businessCollection.add(JSON.parse(JSON.stringify(business)))).pipe(
      catchError(err => throwError(err))
    );
  }

Effect

AddBusiness$ = createEffect(() =>
    this.actions$.pipe(
      ofType(BusinessActions.AddBusiness),
      mergeMap(({ business }) =>
        of(this.businessService.saveBusiness(business)).pipe(
          map(() => BusinessActions.CreateBusinessSuccess()),
          catchError(() => of(BusinessActions.CreateBusinessFailure()))
        )
      )
    )
  );

Action

export const CreateBusinessFailure = createAction(
  '[Business] Failed Creating to database'
);

Component Snippet

actions$
      .pipe(ofType(BusinessActions.CreateBusinessSuccess))
      .subscribe((data) => {
        this.notifyService.showSuccess(
          'Business was saved successfully',
          'Success'
        );
      });
    actions$
      .pipe(ofType(BusinessActions.CreateBusinessFailure))
      .subscribe((data) => {
        this.notifyService.showError(
          'Business was not saved. Please check the information and try again',
          'Failed creating business'
        );
      });
Snipered
  • 53
  • 4

1 Answers1

0

There's no need to catch the error in the service just to throw it again:

saveBusiness(business: BusinessModel) {
    return from(this.businessCollection.add(JSON.parse(JSON.stringify(business)))).pipe(
      catchError(err => throwError(err))
    );
  }

The effect will catch the error (assuming is "add" or JSON.parse throwing the error:

saveBusiness(business: BusinessModel) {
    return from(this.businessCollection.add(JSON.parse(JSON.stringify(business))));
  }

You don't need to create another observable in the effect - get rid of "of()", but note the catchError here now has the error:

AddBusiness$ = createEffect(() =>
    this.actions$.pipe(
      ofType(BusinessActions.AddBusiness),
      mergeMap(({ business }) => this.businessService.saveBusiness(business).pipe(
          map(() => BusinessActions.CreateBusinessSuccess()),
          catchError(( error ) => of(BusinessActions.CreateBusinessFailure( error )))
        )
      )
    )
  );
Eddie Paz
  • 2,219
  • 16
  • 11
  • Thanks, that did the job. Appreciate the help. – Snipered Jan 25 '22 at 00:29
  • You're welcome. I also meant to say something about your component, but I forgot. Your component should not be filtering actions$ to display the message. You should a UI effects that listens for this and call the message service directly. Component should not this additional responsibility. – Eddie Paz Jan 25 '22 at 02:17
  • That makes so much sense, having the component listen for all these events has caused messy code. This one is simple, but others have multiple actions; becomes messy. I will change my code. Thanks. – Snipered Jan 25 '22 at 08:38