@@ -2,7 +2,7 @@ import { Actions, createEffect, ofType } from '@ngrx/effects';
2
2
import { Action , ActionCreator , Creator , props } from '@ngrx/store' ;
3
3
import { ActionCreatorProps , FunctionWithParametersType , NotAllowedCheck , TypedAction } from '@ngrx/store/src/models' ;
4
4
import { Observable , of , Subject } from 'rxjs' ;
5
- import { catchError , map , switchMap , tap } from 'rxjs/operators' ;
5
+ import { catchError , exhaustMap , map , switchMap , take , tap } from 'rxjs/operators' ;
6
6
import { HttpTrackingEntity } from '../model/http-tracking-entity' ;
7
7
import { LoadingState } from '../model/loading-state' ;
8
8
import { convertResponseToError } from './convert-response-to-error' ;
@@ -220,3 +220,44 @@ export const createTrackingEffect = <TRequest, TPayload>(
220
220
)
221
221
)
222
222
) ;
223
+
224
+ export const createTrackingEffectExhaustMap = < TRequest , TPayload > (
225
+ actions$ : Actions ,
226
+ tackingAction : TrackingAction < TRequest , TPayload > ,
227
+ serviceCall : ( request : TRequest ) => Observable < TPayload > ,
228
+ fallbackErrorMsg : string ,
229
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
230
+ successFn : ( httpContext : { request : TRequest ; payload : TPayload } ) => void = httpContext => { }
231
+ ) =>
232
+ createEffect ( ( ) =>
233
+ actions$ . pipe (
234
+ ofType ( tackingAction . loading ) ,
235
+ exhaustMap ( action =>
236
+ serviceCall ( action . request ) . pipe (
237
+ map ( payload => tackingAction . loaded ( { payload } ) ) ,
238
+ take ( 1 ) , // without this take(1) the inner observable will never complete cancelling all subsequent requests
239
+ tap ( successAction =>
240
+ successFn ( {
241
+ request : action . request ,
242
+ payload : successAction . payload ,
243
+ } )
244
+ ) ,
245
+ catchError ( e => {
246
+ console . error ( e ) ;
247
+ const subjectMsg = new Subject < Action > ( ) ;
248
+
249
+ if ( e . error instanceof Blob && e . error . type === 'application/json' ) {
250
+ e . error . text ( ) . then ( ( errorBlobText : string ) => {
251
+ const errorJson = JSON . parse ( errorBlobText ) ;
252
+ subjectMsg . next ( tackingAction . failure ( e , errorJson . error ) ) ;
253
+ } ) ;
254
+ } else {
255
+ return of ( tackingAction . failure ( e , fallbackErrorMsg ) ) ;
256
+ }
257
+ return subjectMsg ;
258
+ } )
259
+ )
260
+ )
261
+ )
262
+ ) ;
263
+
0 commit comments