Reference to this twitter thread: https://twitter.com/jsonberrry/status/1199566382716731393
Subject: "injecting the actions service into the component level as a means for propagating success/error states to a presentational layer"
Question from @jdpearce
"“Injecting the actions service...” woah, woah, woah...what?!
Why aren’t you setting a property in the store and selecting that?"
TL;DR answer: it depends, and if I don't need to store scalar information and can derive the information necessary from just signals flowing down an Observable stream, that alleviates some micromanangement and keeps me aligned to that often seen "don't store what you can derive" principle
The best use case I have for this is for optimistic updates. Here's a contrived example:
Scenario: A "like" button on a post, you can "like" a post and also remove your "like". Also if it fails, we'll get a toast popup that says you can try again.
When using an event sourcing / CQRS pattern we might get a
201 from the API when interacting with the like button.
That represents that the backend has received and accepted our intention of changing state, but the backend process
has not fully finished yet, instead the API is telling us, "OK, cool, thanks we'll get to that."
In keeping with the "don't store what you can derive" principle often occuring in FRP, I only need to know that there was
OK or a
NOT OK signal, I dont' have to store that as scalar data in a state tree, I just need the signal.
In the presentation layer, if the ngrx
Action service is injected,
I can set the "likedness" of a like button as an
Observable<boolean> by using the action service:
postLiked$ = merge( this.actions$.pipe( ofType(postLikedRequestAccepted), mapTo(true), ), this.actions$.pipe( ofType(postUnlikedRequestAccepted), mapTo(false) ) ).pipe( startWith(false), )
Also in the presentation layer, or inside of an Effects class, I can utilize a toast service if the API request failed for some reason
// maybe the showing of the toast is an Observable<boolean> too, // this is just a contrived example postInteractionFailedEffect$ = this.actions$.pipe( ofType(postInteractionFailed), tap(() => this.toastService.getToasty()) )