Search code examples
javascripttypescriptrxjsngrxtslint

RxJS: Unsafe catch usage in effects and epics is forbidden and request nesting


I have an effect, main idea of it is to make some 'magic' with API, the main problem: first I need to make one request, after it's successful I need to make second request. And everything was ok, until I changed my code to this (to look more readable):

@Effect()
    myEffect$ = this.actions$.pipe(
        ofType(actionTypes.SomeDataAction),
        withLatestFrom(this.store.select(selectTheAwesome)),
        concatMap(([action, awesomeData]) =>
            forkJoin([
                of(awesomeData),
                this.myService.makeFirstMagic(
                    action.payload.someDataId
                )
            ])
        ),
        concatMap(data => {
            const [awesomeData, magicFirst] = data;

            return this.myService.makeSecondMagic(awesomeData.awesomeDataId, magicFirst.newId).pipe(
                mergeMap(response => {
                    return [new SomeDataActionSuccess(), new SomeAnotherDataAction([response])];
                })
            );
        }),
        catchError((error) => of(new SomeDataActionError({ error })))
    );

but in result ts-lint fails with RxJS: Unsafe catch usage in effects and epics is forbidden. What I do wrong? Why it used to work (pass linting) with such code?

@Effect()
    myEffect$ = this.actions$.pipe(
        ofType(actionTypes.SomeDataAction),
        withLatestFrom(this.store.select(selectTheAwesome)),
        mergeMap(([action, awesomeData]) => {
            return this.myService.makeFirstMagic(action.payload.someDataId).pipe(
                mergeMap(magicFirst => {
                    return this.myService.makeSecondMagic(awesomeData.awesomeDataId, magicFirst.newId).pipe(
                        mergeMap(response => {
                            return [new SomeDataActionSuccess(), new SomeAnotherDataAction([response])];
                        })
                    );
                })
            );
        }),
        catchError(error => of(new SomeDataActionError({ error })))
    );


Solution

  • You have to use catchError with each service method, e.g.

    this.myService.makeSecondMagic(awesomeData.awesomeDataId, magicFirst.newId).pipe(
                    mergeMap(response => {
                        return [new SomeDataActionSuccess(), new SomeAnotherDataAction([response])];
                    }),
                    catchError(....)
                );