Angular template-driven form: passing data from child component inputs to parent form?

Viewed 29

Seems like this should be a common scenario, but I keep reading conflicting instructions on how to perform it. I have a three child components, each with a series of input controls, that feed into a parent component; however, the parent component never receives the child component's input. My current code is inserted below; sorry if it's a little incomplete, but as I said, I've been reading conflicting theories on how to do this. Thanks in advance!

Child template #1 (partial):

      <input type="text"
        pInputText
        name="name" id="name"
        ngModel #name="ngModel"
        required [minlength]="5" [maxlength]="40"
        placeholder="First LastName"
        (change)="onNameEntered($event)">

Child component:

import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { DropdownOptions } from 'src/assets/dropdownOptions';
import { ApplicantInformation } from 'src/app/_models/applicantInformation.model';


@Component({
  selector: 'app-applicant-information',
  templateUrl: './applicant-information.component.html',
  styleUrls: ['./applicant-information.component.css']
})
export class ApplicantInformationComponent implements OnInit {
  name: string = '';
  phone = '';
  address = '';
  city = '';
  state = '';
  zipCode = '';

  options: any = new DropdownOptions;
  sts: string[] = [];

  @Input() ngModel: any = new ApplicantInformation(this.name,this.phone,this.address,this.city,this.state,this.zipCode)
  @Output() nameEntered = new EventEmitter<{ $event: any }>();
  onNameEntered($event: any) {
    this.nameEntered.emit({$event});
  }

  constructor() {
    this.sts = this.options.strAbbrs;
  }
  ngOnInit(): void {


  }
}

Parent template (partial):

<form #onePlusThreeColumnForm="ngForm">
  ...
  <app-applicant-information
              (nameEvent)="receiveName($event)"></app-applicant-information>
  ...

<button
  type="submit"
  class="p-button p-component"
  [disabled]="!onePlusThreeColumnForm.valid"
  (click)="login(onePlusThreeColumnForm)">
  Submit
</button>
</form>

Parent component:

import { Component, OnInit, ViewChild } from '@angular/core';

import { ApplicantInformation } from 'src/app/_models/applicantInformation.model';
import { BiometricInformation } from 'src/app/_models/biometricInformation.model';

import { ThreeColumn } from '../../_models/threeColumn.model';
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-one-plus-three-column-form',
  templateUrl: './one-plus-three-column-form.component.html',
  styleUrls: ['./one-plus-three-column-form.component.css']
})
export class OnePlusThreeColumnFormComponent implements OnInit {

  firstColumnInformation: any = new ApplicantInformation('','','','','','');
  secondColumnInformation: any = new BiometricInformation('','',0,0,0,'');
  thirdColumnInformation: any = new ApplicantInformation('','','','','','');

  constructor() {
  }

  model = new ThreeColumn(
    this.firstColumnInformation,
    this.secondColumnInformation,
    this.thirdColumnInformation
  );

  ngOnInit(): void {
  }

  name: string = '';

  receiveName($event: any) {
    this.name = $event;
  }

  login(thisForm: NgForm) {
    console.log(this.model);
    console.log(JSON.stringify(thisForm.value));
  }
}

Console result: Console result

1 Answers

(nameEvent)="receiveName($event)"

should be the name of your EventEmitter, ie

(nameEntered)="receiveName($event)"

Related