loading...
Cover image for Observables as Event Engines

Observables as Event Engines

jwp profile image John Peters ・2 min read

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;
      }
   )
}

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;
      }
   )

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);

Subscriptions

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

Simple, terse, and highly responsive.

Easier Implementation?

In Angular, yes there is an easier implementation.

someEvent: EventEmitter<boolean> = 
    new EventEmitter<boolean>();

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>

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
});

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

Posted on by:

jwp profile

John Peters

@jwp

Lit-Html or Svelte?

Discussion

pic
Editor guide