@ngrx The effect does not work the second time

I just started learning @ ngrx / store and @ ngrx.effects and created my first effect in my Angular / Ionic app. It works fine the first time, but if I send the event to the repository again (for example, when the button is pressed again), nothing happens (the network call is not made, nothing is in the console logs). Is there something obvious I'm doing wrong? Here's the effect:

@Effect() event_response$ = this.action$ .ofType(SEND_EVENT_RESPONSE_ACTION) .map(toPayload) .switchMap((payload) => this.myService.eventResponse(payload.eventId,payload.response)) .map(data => new SentEventResponseAction(data)) .catch((error) => Observable.of(new ErrorOccurredAction(error))); 

thanks

+10
source share
2 answers

Sounds like a mistake. In this situation, the action in the observable returned by catch will be selected into the effects stream and the effect will be completed, which will prevent the effect from starting after an error occurs.

Move map and catch to switchMap :

 @Effect() event_response$ = this.action$ .ofType(SEND_EVENT_RESPONSE_ACTION) .map(toPayload) .switchMap((payload) => this.myService .eventResponse(payload.eventId, payload.response) .map(data => new SentEventResponseAction(data)) .catch((error) => Observable.of(new ErrorOccurredAction(error))) ); 

Matching catch within switchMap prevent the effect from executing if an error occurs.

+23
source

You should move map() and catchError() to swithchMap() as follows

 @Effect() public event_response$ = this.action$.pipe( ofType(SEND_EVENT_RESPONSE_ACTION), switchMap((payload) => { return this.myService.eventResponse(payload.eventId,payload.response).pipe( map((data: DataType) => new SentEventResponseAction(data)), catchError((error) => Observable.of(new ErrorOccurredAction(error))) }) ); ); 

Note that the evetResponse() method inside myService must return an observable in order to use pipe later. If your method inside the service returns Promise , you can convert it to observable using from the rxjs package, as shown below:

 import { from } from 'rxjs'; ... const promise = this.myService.eventResponse(payload.eventId,payload.response); const observable = from(promise); return observable.pipe(... 

For a more detailed description, see this link.

0
source

Source: https://habr.com/ru/post/1272686/


All Articles