Sunday, November 24, 2019

Observer and subscriptions in JavaScript

Observers are widely used in JavaScript frameworks such as Angular, libraries like RxJS and others. That is why it is good to know what they do under the hood. The same principle is being successfully utilized by the JavaScript event listeners. More of the intriguing JavaScript aspects you can discover inside the JavaScript for beginners - learn by doing course.

In general, we have a list of subscribers that subscribe to certain events. When certain event emits data, all of its connected subscribers receive the data. The role of an observer is to observe and distribute events to proper subscribers. The simple action of subscribing to an event is referred to as a subscription.


Now to the code:

// we create a class: Observer
class Observer {
inside of its constructor we set up an initially empty list of subscribers.
constructor() {
this.subscribers = [];
}

// function subscribe, just adds subscriber to the subscribers' list
subscribe(subscriber) {
this.subscribers.push(subscriber);
}


// optional: unsubscribe from a particular event, we just remove a subscriber from the subscribers' array. Note that we need to pass as a parameter the whole subscriber object structure containing event and action, to be compared with the existing subscribers inside the this.subscribers array. This is because we would like to distinguish between multiple subscribers for the same event.
unsubscribe(subscriber) {
this.subscribers = this.subscribers.filter(subscriber => subscriber !== subscriber);
}


// inside the publish function, we do several things
publish(event, data) {
 // we search for those subscribers which are subscribed and respond to the same event as the passed function parameter (event)
this.subscribers
.filter(
subscriber =>
subscriber.event === event
)
// then for each list of the found subscribers we propagadate the data parameter i.e. send information to them
.forEach(
subscriber =>
subscriber.action(data)
);
}

}

Now let's see the observer usage in action:

// we first construct object out of our observer class: my_observer
const my_observer = new Observer();

// then we subscribe to event 1, we actually set up the event we will be listening to, as well as what kind of action to be performed when the event is received
my_observer.subscribe({
event: 'event 1',
action: (data) => {
console.log('received event 1', data);
}
});

// now to subscribe to another event
my_observer.subscribe({
event: 'event 2',
action: (data) => {
console.log('received event 2', data);
}
});

// when we have the subscriptions, we will fire up 2 events to event 1, using a delay via setTimeout()
setTimeout(() => {
my_observer.publish('event 1', 'Sending data to event 1 listeners/subscribers');
}, 1500);

// and lets fire up one event to the event 1 subscriber
setTimeout(() => {
my_observer.publish('event 1', 'Sending data to event 2 listeners');
}, 2500);

We should be able to see the 3 events received and being responded to.
Please test the code to see the observers working in action.

Congratulations!

Resources:

JavaScript for beginners - learn by doing

Subscribe To My Channel for updates