DEV Community

Cover image for Observables as Event Engines
John Peters
John Peters

Posted on

Observables as Event Engines

The observable and subscriber go together to create the components of cross component notification system. It's the archetype of the classic Event and Event Handler model. In Angular all EventEmitters are Observables.

Note that the DOM doesn't support the Observable internally. Everything in the DOM still uses the older Event and Event Handler model.

Subscribers and Observables

export class test{
  private subscriber: Subscriber<boolean>;
  const observable$: Observable<boolean> = 
    new Observable<boolean>(
      sub => {
         this.subscriber = sub;
      }
   )
}
Enter fullscreen mode Exit fullscreen mode

This pattern above has two variables, one is a Subscriber, the other is an Observable. the observable is a const because other code will subscribe to the observable, it cannot change without destroying the subscriptions.

The subscriber is used internally to this module only. This is why we use the private keyword.

When a new Observable is created it will pass the subscriber as shown in the lambda expression.

new Observable<boolean>(
// the lambda expression accepting a subscriber.
      sub => {
         // expose this globally 
         this.subscriber = sub;
      }
   )
Enter fullscreen mode Exit fullscreen mode

How do we make change Notifications?

In the test class instance ... we use the subscribers next function as shown here:

this.subscriber.next(true);
//later 
this.subscriber.next(false);
Enter fullscreen mode Exit fullscreen mode

Subscriptions

let test = new Test();
test.observable$.subscribe(valid=>{
   //this is the event handler
});
Enter fullscreen mode Exit fullscreen mode

Simple, terse, and highly responsive.

Easier Implementation?

In Angular, yes there is an easier implementation.

someEvent: EventEmitter<boolean> = 
    new EventEmitter<boolean>();
Enter fullscreen mode Exit fullscreen mode

The recommendation is to allow the event emitter to be decorated with @Output. This allows consumers access for subscription via properties exposed at the HTML layer. While this solution works it has an extra layer of indirection.

//myHandler is an indirect reference to the javascript code.
<app-other (eventEmitter)='myHandler'></app-other>
Enter fullscreen mode Exit fullscreen mode

Use ViewChild Instead of Output

A @ViewChild can also wire up subscriptions as easily. We like this method better as it is more direct. Like this:

@ViewChild(otherComponent) other:OtherComponent;

//direct reference via a lambda expression
other.someEvent.subscribe((valid)=>{
    //do something with the valid event
});
Enter fullscreen mode Exit fullscreen mode

In the code above the HTML doesn't wire up the EventEmitters indirectly, rather they are wired up directly in one line of code.

Summary
If we are using Angular, we will use EventEmitters. If not, we will use the other pattern instead.

JWP2020

Top comments (0)