DEV Community

Manish Kumar
Manish Kumar

Posted on • Originally published at Medium on

Angular Component Communication — Simple yet Powerful Way

Angular Component Communication — Simple yet Powerful Way

Component communication with Angular — Simple yet Powerful Way

Hello,

Lately, I was working on a project where we had too many component communication requirements.

The following were the possible solutions to achieve our goals:

  • Parent/Child components could communicate using @Input and @Output
  • Using the RxJs’s Subjects for component communication, not having the parent/ child relationship

We proceeded with creating Input/Output’s and Subjects, but later in the development cycle, we realized that we ended up having too many Input/Outputs and Subjects created and listener for each type of communication we had.

To simplify this equation a bit, we created a simple yet powerful service to handle the component communication. The idea was, instead of creating multiple Subject or Input/output setups, to create one service that can broadcast messages to all of the listeners, and observers can decide if the broadcasted message is interesting or not.

Here we go, ‘event.service.ts’:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

export interface IMessageProps<T> {
    action: string;
    payload: T;
}

@Injectable()
export class EventService {

// Subject subscription
private _message = new Subject();
get message() {
    return this._message.asObservable();
}

constructor() { }

// Subject broadcast
    broadcast<T = any>(action: string, payload: T = null) {
        this._message.next({
            action: action,
            payload: payload
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

Key Points

  1. If you look closely, it’s following the terminology from the Redux world, i.e. action and payload.
  2. Each broadcasted message will carry the message information.
  3. Observers listening to the messages can process the messages useful to them.

Broadcasting a Message

Broadcasting a message is as simple as calling a method on the event service with the required information.

// Angular imports and metadata goes here...
class PublisherComponent {

constructor(private eventService: EventService) {}

deleteUser() {
    this.eventService.broadcast({
      action: 'DELETE_USER',
      payload: {
        Id: 123
      }
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

As we see here, we are calling the broadcast message as defined in the interface IMessageProps. We are defining the message/action type and the payload to process that message.

Listening to the Message

As our event service is nothing but the RxJs’s Subject, listening/subscribing to Subject should be simple enough.

// Angular imports & metadata goes here...
class SubscriberComponent implements OnInit, OnDestroy {
  eventSubscription: Subscription;

constructor(private eventService: EventService) {}

ngOnInit() {
    this.eventSubscription = this.eventService.message.subscribe(
      (message: IMessageProps) => {
        switch (message.action) {
          case 'DELETE_USER':
            this._deleteUser();
            break;
        }
      }
    );
  }

ngOnDestroy() {
    this.eventSubscription.unsubscribe();
  }

private _deleteUser() {
    // your code goes here
  }
}
Enter fullscreen mode Exit fullscreen mode

As we see here, the Subscriber component is listening to the messages, and if the broadcasted message is of type DELETE_USER, that will be processed. The rest all will be ignored (simply because the listener component is not interested in the rest of the messages).

And that’s it. We are done. We have component communication that is much simpler, more organized, and easier to understand.

Let me know your thoughts on it.

Connect with me at:

Twitter: https://twitter.com/mkdudeja

LinkedIn: https://www.linkedin.com/in/mkdudeja/

Thanks,
Manish K. Dudeja

Top comments (3)

Collapse
 
michaeljota profile image
Michael De Abreu

Maybe you could try NgRx for this cases. I think losing typechecking (because you can't check the actions or if you want to the combination of actions/payloads would probably end up the same way as NgRx manage them.

Collapse
 
mkdudeja profile image
Manish Kumar

Ngrx undoubtedly a great tool, but as the saying is, "Great power comes at some cost." Ngrx will cause lots of boilerplate code to be setup in terms of actions, reducers, effects for every feature.

Might not be good fit for small to mid-size apps. This post as the title says, "simple yet powerful way" tries to use the same principle for component communication without adding too much of code or additional library in the codebase and best suited for all size of projects.

Collapse
 
michaeljota profile image
Michael De Abreu

I don't think that if you need and event system the app is small to mid in size. Also, have you checked out NgRx lately? They have updated the tooling and the boilerplate has become minimal for most of things.