RxJS
RxJS: Reactive Extensions for JavaScript
We need RxJS to handle asynchronous data easily
Asynchronous data: Data from HTTP response, data from a port, user click events, timer etc
Observer and Observable
Observer: RxJS object that emits data stream
Observable: Entity that is listening to the stream
In order to initiate communication between data and listener in RxJS scope, first they need to be converted to "observer" and "observable"Observer subscribes to the observable to listen to the data stream
Use of "subscribe:" Used to listen to the data stream
OPERATORS
Operators are small pieces of code that can be applied as pre-processing logic before data comes to the listenerSummary of common operators:
map: used to manipulate responses from the API
filter: used to filter values based on condition. Same as ES6 filter but this is for Observable
merge: This operator combines a number of observables streams and concurrently emits all values from every given input strea. The stream completes when all input streams complete and will throw an error if any of the streams throws an error. It will never complete if some of the input streams don’t complete. Use this operator if you’re not concerned with the order of emissions and is simply interested in all values coming out from multiple combined streams as if they were produced by one stream.
concat: only when 1 observable completes, it it will start with the next observable. Use this operator if the order of emissions is important and you want to first see values emitted by streams that you pass first to the operator. For example, you may have an observable sequences that delivers values from a cache and another sequence that delivers values from a remote server. Use concat if you want to combine them and ensure that the value from cache is delivered first.
from: Turns array/promise/iterable into Observable
delay: emits a value with delay
debouncetime: discards emitted values if a certain time didnt pass between the last input
distinctuntilchanged: Only emits value if it is distinct from the previous one
PROMISE vs OBSERVABLE
|
Promise |
Observable |
| Are not lazy: executes immediately after creation. | Are lazy: they’re not executed until we subscribe to them using the subscribe() method. |
|
Are not
cancellable. |
Have
subscriptions that are cancellable using the unsubscribe() method, which
stops the listener from receiving further values. |
| Don’t provide any operations. |
|
REAL-TIME USAGE
Note: Used angular 12+ for the below examples
Each button here triggers a function that runs its corresponding RxJS operators example
Now, let us start writing functions that execute on click of each of these buttons
map: used to manipulate responses from the API
flatMap – to create new Observable basing on the data emitted by another Observable
forkJoin-will wait for all passed observables to complete and then it will emit an array or an object with last values from corresponding observables. The possible use-case for it is running many parallel networks requests. It accepts an array of Observables and returns higher-order Observable.
tap: to perform side actions whenever an Observable emits new data
SWITCHMAP
It will cancel any ongoing request whenever there is a new request. The previous call was outdated and we do not want to waste an API call for an outdated request.
Example: when we have a search box that makes API request as the user types into the box.
Notice how the first request was canceled since the user quickly typed even before the previous call was complete.
However in a real time scenario, it is always better to use "debounceTime": Emits a notification from the source Observable only after a particular time span has passed without another source emission.
MERGEMAP
Consider the same example as above but with "mergeMap"
CONCATMAP
Consider the same example as above but with "concatMap"
COMBINELATEST
Consider you have two different observables. But you want to get the latest from both whenever there is new data
let obs1 = new BehaviorSubject('initital-obs1');
let obs2 = new BehaviorSubject('initital-obs2');
setTimeout(() => {
obs2.next('obs-2 after 5 secs');
}, 5000);
setTimeout(() => {
obs1.next('obs-1 after 2 secs');
}, 2000);
setTimeout(() => {
obs2.next('obs-2 after 2 secs');
}, 2000);
setTimeout(() => {
obs2.next('obs-2 again after 2 secs');
}, 2000);
combineLatest([obs1, obs2]).subscribe((res) => console.log(res));
SUBJECT
Subject is the equivalent to an EventEmitter, and the only way of multicasting a value or event to multiple Observers. Subject is both an observable and an observer.
It’s an observable because it implements the subscribe() method, and it’s also an observer because it implements the observer interface — next(), error(), and complete().
BehaviourSubject:
Same as Subject but a BehaviorSubject holds one value. When it is subscribed it emits the value immediately. A Subject doesn't hold a value
Ex: Consider we have the below angular service. messages$ is public and can be subscribed for latest values by subscribers from any component
Consider we have component, may be called as "HelloComponent" which displays the subscribed message value from the service
We can set the value for this message from any component, any change in the value will update in all components that was subscribed to it and gets this new value
Stackblitz code reference link: https://stackblitz.com/edit/angular-ivy-cumzob?file=src/app/app.component.ts
For the output: https://angular-ivy-au21hw.stackblitz.io
Stackblitz for switchMap, mergeMap, concatMap: https://stackblitz.com/edit/base-angular-12-app-crzqez










Comments
Post a Comment