Search code examples
angularformsprojection

Angular: get access to projected FormGroup


I want to create a base form component, that will have additional control over all other forms.

For example, I want to check whether the form is dirty, when user wants to close the form, or not.

Here is my base component form sample:

@Component({
  selector: 'my-modal-form',
  templateUrl: './modal-form.component.html',
  styleUrls: ['./modal-form.component.scss']
})
export class ModalFormComponent implements OnInit, AfterContentInit {

  @ContentChild(FormGroup, { static: false }) usersForm: FormGroup;

  constructor() { }

  ngOnInit(): void {
    console.log(this.usersForm);
  }
  ngAfterContentInit() {
    console.log(this.usersForm);
  }
}

And here is usage example:

<my-modal-form>
  <form [formGroup]="profileForm">
    <input type="text" formControlName="firstName" />
    <input type="text" formControlName="lastName" />
  </form>
</my-modal-form>

So both console.log calls gives me undefined. Here I want to get access to FormGroup instance so I can check is it dirty or not.

The question is - how to correctly get access to projected form (FormGroup)?


Solution

  • Using ControlContainer instead seems to work*:

    Stackblitz

    import { Component, ContentChild, OnInit, AfterContentInit } from '@angular/core';
    import { ControlContainer, FormGroup } from '@angular/forms'
    
    @Component({
      selector: 'modal-form',
      template: `
        <ng-content></ng-content>
      `
    })
    export class ModalFormComponent implements OnInit, AfterContentInit {
    
      @ContentChild(ControlContainer, { static: true }) formGroup: FormGroup;
    
      constructor() { }
    
      ngOnInit(): void {
        console.log(this.formGroup.value); // null
      }
    
      ngAfterContentInit() {
        console.log(this.formGroup.value); // {firstName: "", lastName: ""}
        this.formGroup.valueChanges.subscribe(console.log)
      }
    }
    

    *caveat - I've not tried this approach so cannot assess it's viability. Perhaps OP can comment / answer post down line if viable?