Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do two way data stream between parent and child components? (Angular 5)

Tags:

angular

I have a simple code example where I try sending from parent component data into child component and at the same time get it data from child to parent when data will be changed:

Parent:

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {

  parentData:string = 'start value'

}
<app-child [childData]="parentData"></app-child>

Child:

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent {

  @Input() childData: string;

}
<p>
    {{childData}}
    <br>
    <input [(ngModel)]="childData" type="text">
</p>

I need to annotate @Output() for childData but it already annotated with @Input(). How to binding variables childData and parentData?

like image 229
Pavel Avatar asked Oct 26 '25 18:10

Pavel


2 Answers

As mentioned in this article:

To create your own component that supports two-way binding, you must define an @Output property to match an @Input, but suffix it with Change.

You can see an example for your code in this stackblitz.

Child component:

<input [(ngModel)]="childData" type="text" (ngModelChange)="onModelChange($event)">
export class AppChildComponent {
  @Input() childData: string;
  @Output() childDataChange = new EventEmitter<string>();

  onModelChange(value: string) {
    this.childDataChange.emit(value);
  }
}

Parent component:

<app-child [(childData)]="parentData"></app-child>
like image 51
ConnorsFan Avatar answered Oct 29 '25 08:10

ConnorsFan


I like creating a service that both parent and child can subscribe to as well as set.

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

@Injectable()
export class ShareDataService {

  private subjectSharedData: Subject<any> = new Subject<any>();
  getSharedData$ = this.subjectSharedData.asObservable();

  setSharedData(data: any): void {
    this.subjectSharedData.next(data);
  }

}

At points where you need to pass the data you call the service method to setSharedData(data) the data whether child or parent. Where you want to retrieve, use getSharedData$.subscribe(data => { console.log(data); }).

You will need to import this service in your app.module.ts or which ever module. Then instantiate it in the constructor method of both the parent and child components.

Let me know if you have any questions.

like image 35
Andrew Lobban Avatar answered Oct 29 '25 08:10

Andrew Lobban



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!