I have a nested child component that have a output Event, I want listen this event from parent component but I dont know how, I have 4 levels:
I tried to pass the event from child 3 to child 2 and child 2 to child and to Parent, but I think that this is not the best way.
-Parent (From this I want listen the event)
--Child
----Child 2
------Child 3 (This have the Event)
Though you can use an @Output
event emitter to do this, I'd suggest that you create a shared service instead that will handle the communications since there are quite many levels of nesting.
You can do something like below, and inject the service in both of your components. One will emit the message (your nested child component), and one will listen for the messages (your top level component).
Define your service
@Injectable({
providedIn: 'root'
})
export class CommunicationService {
@Output() message$: EventEmitter<boolean> = new EventEmitter();
sendMessage(message: String) {
this.change.emit(message)
}
}
Inject it in your components
constructor(private communicationService: CommunicationService) { }
In the component where you will send the message from
sendMessage() {
this.communicationService.sendMessage('This is a message from deep below!');
}
And in your listener component, subscribe to the event emitter
ngOnInit() {
this.communicationService.message$.subscribe(message => {
console.log(message);
});
}
Source Dan Wahlin (ng-conf: Mastering the Subject: Communication Options in RxJS ), it's not recommanded to use OutPut when you have a component in a deeper level that has to communicate with a higher lever component , imagine you have 5 or 6 leves!!, you have to use Subject instead: you can create and Event bus through an observable service
Events here is an enum of events if you want
export enum Events{
'payment done',
// other events here
}
@Injectable()
export class EventService {
private subject$ = new Subject()
emit(event: EmitEvent) {
this.subject$.next(event);
}
on(event: Events, action: any): Subscription {
return this.subject$.pipe(
filter((e: EmitEvent) => e.name == event),
map((e: EmitEvent) => e.value)).subscribe(action);
}
}
so now imagine that you want to emit an event from Child3 , let's say for example after a payment is done => notify parent component
export class Child3Component implements OnInit {
constructor(public eventservice : EventService ) {}
pay(paymentAmount: any) {
this.eventservice.emit(
new EmitEvent('payment done',paymentAmount));
}
}
now in your parent component you can call on method like this and you will get the event
export class ParentComponent implements OnInit {
constructor(public eventservice : EventService ) {}
ngOnInit() {
this.eventservice.on('payment done', (paymentAmount => console.log(paymentAmount));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With