23

I'm very new in angular 2. I have a problem to communicate between two components. When I have a layout with a parent and some child components, it's easy to set variables of the child components with the @Input annotation.

But now I have a layout of one parent component (which is mostly for the layout) and two child components:

example Layout

The child component 2 have a bunch of buttons, which creates only a simple message. Now I want to display this message in child component one.

How do I resolve it? Thanks in advance

Liam
  • 27,717
  • 28
  • 128
  • 190
Marco Rehmer
  • 1,033
  • 2
  • 12
  • 32

4 Answers4

33

Beside the solutions using the @Input/@Output and a parent component as a 'bridge', a common way would also be introducing a shared service. The service needs to be provided in a parent component so the children can share single instance of the service (How do I create a singleton service in Angular 2?).

Basic example using the BehaviorSubject as a delegate:

@Injectable()
export class SharedService {

    messageSource: BehaviorSubject<string> = new BehaviorSubject('');

    constructor() { }
}

Child component 1:

export class ChildComponent1 {

    constructor(private sharedService: SharedService) { }

    sendMessage(): void {
        this.sharedService.messageSource.next('Hello from child 1!');
    }
}

Child component 2:

export class ChildComponent2 {

    constructor(private sharedService: SharedService) { }

    ngOnInit(): void {
        this.sharedService.messageSource.subscribe((message) => {
            console.log('Message: ', message); // => Hello from child 1!
        });
    }
}

See also: Angular2 - Interaction between components using a service

seidme
  • 12,543
  • 5
  • 36
  • 40
19

A simple way is to set an output with @Output in your child component2 as an eventemitter and emit a event with the message passed as a data of it when a button is clicked. Then, listen to this event in your parent component and update a property that is set as an input of your child component1 when the event occurs.

The image below is an example that clearly show the mechanism

Component-IO

Faly
  • 13,291
  • 2
  • 19
  • 37
16

You can use template variables to reference siblings:

<child1 #child1></child1>
<child2 (someOutput)="child1.doSomething($event)"></child2>
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
9

You can use @ViewChild and @Output to update the properties in the child component.

Alternatively you can use @Input in place of @ViewChild.

The approach suggested by seidme will also work just fine. It just depends on your use case.

Example using @ViewChild and @Output: https://plnkr.co/edit/r4KjoxLCFqkGzE1OkaQc?p=preview

Example using @Input and @Output https://plnkr.co/edit/01iRyNSvOnOG1T03xUME?p=preview

JSNinja
  • 705
  • 6
  • 19