title: Pub-Sub implementation for Angular 5 application
body: <p>Have been looking for something similar to <strong>IEventAggregator</strong> in WPF-Prism framework. </p>
  
  <p><a href="https://stackoverflow.com/questions/33958805/is-there-an-event-pub-sub-framework-for-angular">This</a> is somewhat the same question in my mind, except that looking for a solution in Angular 5.</p>
  
  <p>Couldn't find a simple solution so far. Had to create one myself using <strong>typescript generics</strong>, <strong>angular dependency injection</strong> using services and <strong>"rxjs/Subject"</strong>.</p>
  
  <p>It is mostly inspired by <a href="http://jasonwatmore.com/post/2016/12/01/angular-2-communicating-between-components-with-observable-subject" rel="nofollow noreferrer">this</a> post.</p>
  
  <p>A service named <code>EventService</code> is created and registered as a dependency in the <code>AppModule</code>. Since it is added in the <code>NgModule.providers</code> list of <code>AppModule</code>, it can be resolved as a dependency in any component.</p>
  
  <p>EventService:</p>
  
  <pre><code>/**
   * For inter component communication throughout application.
   * Use dependency injection to raise an event with payload.
   * NOTE: All subscriptions to be unsubscribed at ngOnDestroy() method of subscribing component
   */
  @Injectable()
  export class EventService {
  
      private someDataChangeEvent: IEvent&lt;string&gt; = new Event&lt;string&gt;();
  
      constructor() { }
  
      public get someDataChange(): IEvent&lt;string&gt; {
          return this.userImageChangeEvent;
      }
  
  }
  </code></pre>
  
  <p>where IEvent and Event is:</p>
  
  <pre><code>import { Subscription } from "rxjs";
  import { Subject } from "rxjs/Subject";
  
  export interface IEvent&lt;T&gt; {
  
      /**
       * Method which will signal the subscribers.
       * @param payload 
       */
      publish(payload: T): void,
  
      /**
       * Registers the payload receiving function.
       * NOTE: Subscribing component should handle the subscription disposal on ngOnDestroy method.
       * @param callback: callback function 
       */
      subscribe(callback: (payload: T) =&gt; void): Subscription
  }
  
  export class Event&lt;T&gt; implements IEvent&lt;T&gt; {
  
      private subject = new Subject&lt;any&gt;();
  
      constructor() { }
  
      public publish(payload: T): void {
          // Notify subscribers.
          this.subject.next(payload);
      }
  
      public subscribe(callback: (payload: T) =&gt; void): Subscription {
          // Create a subscription with the passed callback
          let subscription = this.subject.asObservable().subscribe(callback);
          return subscription;
      }
  }
  </code></pre>
  
  <p>At the publishing component</p>
  
  <p>1.Constructor - resolve dependency:</p>
  
  <pre><code>constructor(
    private readonly _eventService: EventService
  ) { }
  </code></pre>
  
  <ol start="2">
  <li><p>Publish event when the data changes. Say, httpClient get complete or drop down item change or a button click. <code>payload</code> is the data you are sending to the subscribing component.</p>
  
  <pre><code>self._eventService.someDataChange.publish(payload);
  </code></pre></li>
  </ol>
  
  <p>Now, at the subscribing component/s</p>
  
  <ol>
  <li>Implement OnInit and OnDestroy</li>
  <li>Constructor - resolve the dependency, same as above</li>
  <li>In the ngOnInit method, subscribe event</li>
  <li><p>In the ngOnDestroy unsubscribe subscription.</p>
  
  <pre><code>export class SomeComponent implements OnInit, OnDestroy {
  
    constructor(
      private readonly _eventService: EventService
    ) { }
  
    private eventSubscription: Subscription = null;
  
    ngOnInit() {
      this.eventSubscription = this._eventService.someDataChange.subscribe((payload) =&gt; {
        // Do something with payload
      });
    }
  
    ngOnDestroy() {
      this.eventSubscription.unsubscribe();
    }
  }
  </code></pre></li>
  </ol>
  
  <p>I can define as many different events as application needs and multiple components can subscribe to these events. But all these subscriptions I need to carefully dispose of at the ngOnDestroy method.</p>
  
  <p>Is there a way to avoid it? Is there a way to automatically delete the subscription, on the component destroy without doing it explicitly.</p>
  
  <p>With one or two events across application, this works fine. 
  But with more than 10 events registered in <code>EventService</code>, multiple components subscribing most of the events, I doubt is this a good solution?</p>
  
  <p>What are my alternatives? At the least, an automatic unsubscribe for disposed of components will be a great help. Thank you.</p>