1
votes

I have 3 components, 2 child and 1 parent. I have save button in parent component, for getting child data in parent, I have tried this:

<div class="border border-dark p-1 m-1">
  <basic-details
    *ngIf="customerData"
    [formType]="formType"
    [customerDetails]="customerData"
    #customerDetails
  ></basic-details>
</div>
<div class="border border-dark p-1 m-1">
  <verification-details
    *ngIf="customerData"
    [formType]="formType"
    [customerDetailsForKyc]="customerData"
    #customerDetailsForKyc
  ></verification-details>
</div>

<div class="row main justify-content-center">
  <button class="btn btn-primary" (click)="save(customerDetails, customerDetailsForKyc)">Save</button>
  <button class="btn btn-primary ml-2" (click)="cancel()">Cancel</button>
</div>

ts file

save(basic, kyc) {
    console.log('basic', basic);
    console.log('kyc', kyc);
  }

For basic-details component, I am getting proper data in my parent component in save button click, but for verification-details I am getting following error:

In both child component I am getting data using @Input() like this:

for basic component:

@Input() customerDetails: ICustomerDetailsData;

for verification component

@Input() customerDetailsForKyc;

Is something I am doing wrong?

3
Can you share TS and html for both child component? - SJNF
I have tried for you but It worked for both child component for me LINK STACKBLITZ. Please let me know. - SJNF
can you please give the 3 ts files of each component - hous
@Linker Added please check, is there something I did wrong? - techguy
@techguy I'm afraid that this isn't enough to understand all the situation, if you can share all the content of the files it'll be better. Though, try to add : ICustomerDetailsData; also for the second input - hous

3 Answers

1
votes

I have a working example of your code, two child and one parent. As you described in your question, I have used almost similar things in my code. You did not mention about [formType]="formType", that's why I did not use it. Please check my code. It is working in StackBlitz ==> Angular two way data binding between parent and child co acqylp

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `<app-children [(data)]="message"  
              [customerDetails]="customerData"
              #customerDetails></app-children>
             <br><br>
             <app-children2 [(data)]="message2" 
              
             [customerDetailsForKyc]="customerData"
             #customerDetailsForKyc></app-children2>
            <div>Parent: {{message}}
            <br>
            <button class="btn btn-primary" (click)="save(customerDetails, customerDetailsForKyc)">Save</button>
            </div>`,
})

export class AppComponent {
  public message: string;
  public message2: string;
  customerData:ICustomerDetailsData={color:'TTT',width:15};
  ngOnInit() {
    this.message = 'Original message'
    this.message2 = 'Original message2'
  }
  save(basic, kyc) {
    console.log('basic', basic);
    console.log('kyc', kyc);
  }
}

@Component({
  selector: 'app-children',
  template: `<div>Children: {{data}}</div> 
              <br>
              <input type="text" class="form-control" id="name"
     
              [(ngModel)]="data" >
              <br>
             <a (click)="changeMessage('Children message')">Click me!</a>`
})

export class ChildComponent {
  @Input() public data: string;
  @Input() customerDetails: ICustomerDetailsData;
  @Output() dataChange= new EventEmitter<string>();
  changeMessage(message: string) {
    this.data = message;
    this.dataChange.emit(this.data);
  }
}

 @Component({
  selector: 'app-children2',
  template: `<div>Children: {{data}}</div> 
             <a (click)="changeMessage('Children message')">Click me!</a>`
})

export class ChildComponentNew {
    @Input() customerDetailsForKyc;
  @Input() public data: string;
  @Output() dataChange= new EventEmitter<string>();
  changeMessage(message: string) {
    this.data = message;
    this.dataChange.emit(this.data);
  }
}
interface ICustomerDetailsData {
  color?: string;
  width?: number;
}
0
votes

One other option to get data from child to parent is to use @ViewChild decorator in order to inject child component to parent. So, when save button is clicked you should be able to take data of your child components. Check ViewChild | Angular

0
votes

Original Text

  1. Your method: save(customerDetails, customerDetailsForKyc)" uses as arguments template variables. It is wrong, because they have other goals. "Template variables help you use data from one part of a template in another part of the template. With template variables, you can perform tasks such as respond to user input or finely tune your application's forms." Template variables | Angular.
  2. If you want to send data in the parent component (pass child component data into parent) so use to decorator @Output Sharing data between child and parent directives and components | Angular