import { createEffect, ofType, Actions } from '@ngrx/effects'; import { Action, ActionCreator } from '@ngrx/store'; import { Creator } from '@ngrx/store/src/models'; import { Observable, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; export function mwCreateApiEffect< E extends Extract, AC extends ActionCreator, TApiResult, T extends string | AC, U extends Action = Action, V = T extends string ? E : ReturnType> >( actions$: Actions, action: T, apiServiceCall: (actionParams: V) => Observable, resultCallback: (result: TApiResult, actionParams: V) => Action, errorCallback?: (err: any, actionParams: V) => Action ): Observable { const apiServiceCall$ = (actionParams: V): Observable => { let stream$ = apiServiceCall(actionParams).pipe( map((result: TApiResult) => resultCallback(result, actionParams)) ); if (errorCallback) { stream$ = stream$.pipe( catchError((err) => of(errorCallback(err, actionParams))) ); } return stream$; }; const actionsSourceResult = actions$.pipe( ofType(action) as any, switchMap((actionParams) => apiServiceCall$(actionParams as any)) ); return createEffect(() => actionsSourceResult as any); }