| 29 | |
| 30 | @Injectable() |
| 31 | export class EntityEffects { |
| 32 | // See https://github.com/ReactiveX/rxjs/blob/master/doc/marble-testing.md |
| 33 | /** Delay for error and skip observables. Must be multiple of 10 for marble testing. */ |
| 34 | private responseDelay = 10; |
| 35 | |
| 36 | /** |
| 37 | * Observable of non-null cancellation correlation ids from CANCEL_PERSIST actions |
| 38 | */ |
| 39 | cancel$: Observable<any> = createEffect( |
| 40 | () => |
| 41 | this.actions.pipe( |
| 42 | ofEntityOp(EntityOp.CANCEL_PERSIST), |
| 43 | map((action: EntityAction) => action.payload.correlationId), |
| 44 | filter((id) => id != null) |
| 45 | ), |
| 46 | { dispatch: false } |
| 47 | ); |
| 48 | |
| 49 | // `mergeMap` allows for concurrent requests which may return in any order |
| 50 | persist$: Observable<Action> = createEffect(() => |
| 51 | this.actions.pipe( |
| 52 | ofEntityOp(persistOps), |
| 53 | mergeMap((action) => this.persist(action)) |
| 54 | ) |
| 55 | ); |
| 56 | |
| 57 | constructor( |
| 58 | private actions: Actions<EntityAction>, |
| 59 | private dataService: EntityDataService, |
| 60 | private entityActionFactory: EntityActionFactory, |
| 61 | private resultHandler: PersistenceResultHandler, |
| 62 | /** |
| 63 | * Injecting an optional Scheduler that will be undefined |
| 64 | * in normal application usage, but its injected here so that you can mock out |
| 65 | * during testing using the RxJS TestScheduler for simulating passages of time. |
| 66 | */ |
| 67 | @Optional() |
| 68 | @Inject(ENTITY_EFFECTS_SCHEDULER) |
| 69 | private scheduler: SchedulerLike |
| 70 | ) {} |
| 71 | |
| 72 | /** |
| 73 | * Perform the requested persistence operation and return a scalar Observable<Action> |
| 74 | * that the effect should dispatch to the store after the server responds. |
| 75 | * @param action A persistence operation EntityAction |
| 76 | */ |
| 77 | persist(action: EntityAction): Observable<Action> { |
| 78 | if (action.payload.skip) { |
| 79 | // Should not persist. Pretend it succeeded. |
| 80 | return this.handleSkipSuccess$(action); |
| 81 | } |
| 82 | if (action.payload.error) { |
| 83 | return this.handleError$(action)(action.payload.error); |
| 84 | } |
| 85 | try { |
| 86 | // Cancellation: returns Observable of CANCELED_PERSIST for a persistence EntityAction |
| 87 | // whose correlationId matches cancellation correlationId |
| 88 | const c = this.cancel$.pipe( |
nothing calls this directly
no test coverage detected