Observable
Observables provide support for passing messages between parts of the application. They are a technique for event handling, asynchronous programming and handling multiple value.
In an Observer pattern, there are two primary entities: 1. Subject 2. Observers. Subject, which is an object, maintains a list of dependents which are known as Observers. Subject notifies all the Observers automatically when there is a state change.
Observables are declarative in nature. An Observer must subscribe to an Observable in order to recieve any values.
An Observable can deliver multiple values such as literals, messages or events depending on the context.
Publish⚑
To create a new Observable, a publisher must instantiate Observable
. This
instance provides sunscribe()
method. Observable
instance expects a
function as an argument. This function is responsible for generating data that
is supposed to be returned the subscribers.
// source: https://angular.io/guide/observables
const locations = new Observable((observer) => {
let watchId: number;
// Simple geolocation API check provides values to publish
if ("geolocation" in navigator) {
watchId = navigator.geolocation.watchPosition(
(position: GeolocationPosition) => {
observer.next(position);
},
(error: GeolocationPositionError) => {
observer.error(error);
}
);
} else {
observer.error("Geolocation not available");
}
// When the consumer unsubscribes, clean up data ready for next subscription.
return {
unsubscribe() {
navigator.geolocation.clearWatch(watchId);
},
};
});
// Call subscribe() to start listening for updates.
const locationsSubscription = locations.subscribe({
next(position) {
console.log("Current Position: ", position);
},
error(msg) {
console.log("Error Getting Location: ", msg);
},
});
// Stop listening for location after 10 seconds
setTimeout(() => {
locationsSubscription.unsubscribe();
}, 10 * 1000);
Definitions⚑
Notification Type | Description |
---|---|
next |
Required. handler for each delivered value. Called zero or more times after execution starts |
error |
Optional. handler for error notification. halts execution of observable instance |
complete |
Optional. hadler for execution-complete notification. delayed values can continue to be delivered to the next handler after execution is complete |
Subscribe⚑
Observables would not deliver anything until there's a subscriber. Any
code-block/function can subscribe to an Observable instance using the method
subscribe()
. subscribe()
method expects three handlers namely next()
,
error()
and complete()
. Out of the three handlers, only the next()
is
required. There are two ways to pass these arguments. Refer to the following
code-block for an illustration.
// of() is a function that creates observable instance. `rxjs` provides this function
const myObservable= of(1, 2, 3);
//>>>>>>>>>> METHOD 1
// observer object
const observers = {
next(x: number) {
console.log('next value is', x);
},
error(err: Error) {
console.log(err.message);
}
complete() {
console.log('observable complete');
}
}
myObservable.subscribe(observers);
//>>>>>>>>>>>> METHOD 2
// subscribe() method can accept callback functions
myObservable.subscribe(
x => console.log(`next value is ${x}`),
err => console.log(`error in observable ${err.message}`),
() => console.log('observable completed')
)
Multicasting⚑
Multicasting is the practice of broadcasting to a list of multiple subscribers in a single execution context. Normally, an Observable creates an independent execution context for each subscribed observers. This behaviour is not always required. Multicasting helps solve this issue.
// TODO: write examples for multicasting