Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass the FormGroup of a parent component to its child component using the current Form API

I would like to pass the parent component's FormGroup to its child for the purpose of displaying an error-message using the child.

Given the following parent:

parent.component.ts

import { Component, OnInit } from '@angular/core' import {   REACTIVE_FORM_DIRECTIVES, AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'  @Component({   moduleId: module.id,   selector: 'parent-cmp',   templateUrl: 'language.component.html',   styleUrls: ['language.component.css'],   directives: [ErrorMessagesComponent] }) export class ParentCmp implements OnInit {   form: FormGroup;   first: AbstractControl;   second: AbstractControl;      constructor(private _fb: FormBuilder) {     this.first = new FormControl('');     this.second = new FormControl('')   }      ngOnInit() {     this.form = this._fb.group({       'first': this.first,       'second': this.second     });   } } 

I would now like to pass the form:FormGroup variable above to the child component below:

error-message.component.ts

import { Component, OnInit, Input } from '@angular/core' import { NgIf } from '@angular/common' import {REACTIVE_FORM_DIRECTIVES, FormGroup } from '@angular/forms'  @Component({   moduleId: module.id,   selector: 'epimss-error-messages',   template: `<span class="error" *ngIf="errorMessage !== null">{{errorMessage}}</span>`,   styles: [],   directives: [REACTIVE_FORM_DIRECTIVES, NgIf]   }) export class ErrorMessagesComponent implements OnInit {   @Input() ctrlName: string    constructor(private _form: FormGroup) { }    ngOnInit() { }    get errorMessage() {     // Find the control in the Host (Parent) form     let ctrl = this._form.find(this.ctrlName);     console.log('ctrl| ', ctrl);  //    for (let propertyName of ctrl.errors) { //      // If control has a error //      if (ctrl.errors.hasOwnProperty(propertyName) && ctrl.touched) { //        // Return the appropriate error message from the Validation Service //        return CustomValidators.getValidatorErrorMessage(propertyName); //      } //    }      return null;   } 

The constructor formGroup represents the FormGroup of the parent - in its present form it does not work.

I am trying to follow this obsolete example at http://iterity.io/2016/05/01/angular/angular-2-forms-and-advanced-custom-validation/

like image 922
st_clair_clarke Avatar asked Jul 23 '16 23:07

st_clair_clarke


People also ask

How do you communicate between parent and child components?

@Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.


Video Answer


1 Answers

In the parent component do this:

<div [formGroup]="form">   <div>Your parent controls here</div>   <your-child-component [formGroup]="form"></your-child-component> </div> 

And then in your child component you can get hold of that reference like so:

export class YourChildComponent implements OnInit {   public form: FormGroup;    // Let Angular inject the control container   constructor(private controlContainer: ControlContainer) { }    ngOnInit() {     // Set our form property to the parent control     // (i.e. FormGroup) that was passed to us, so that our     // view can data bind to it     this.form = <FormGroup>this.controlContainer.control;   } } 

You can even ensure either formGroupName or [formGroup] is specified on your component by changing its selector like so:

selector: '[formGroup] epimss-error-messages,[formGroupName] epimss-error-messages' 

This answer should be sufficient for your needs, but if you want to know more I've written a blog entry here:

https://mrpmorris.blogspot.co.uk/2017/08/angular-composite-controls-formgroup-formgroupname-reactiveforms.html

like image 157
Peter Morris Avatar answered Sep 22 '22 10:09

Peter Morris