angularformsangular-reactive-formsangular-providers

Angular form: Equivalent of constructor ngForm injection for Reactive Forms?


I am trying to build a component to show validation error messages like this:

<form>
  <input ngModel name="firstname" required>
  <validation-error for="firstname"></validation-error> 
</form>

The <validation-error> component is amazingly simple for Template Driven forms as we can inject the NgFrom in the constructor and use ngFrom.form.get(myControlName) to find a control an its state:

@Component({
  selector: 'validation-error',
  template: `{{errorText}}`,
  styles: [`:host { display:block; color:red; }`]
})
export class ValidationErrorComponent  {
  @Input() for: string;  // name of input element
  constructor(
    @Optional() private ngForm: NgForm  // This works for Template forms only.
  ) { }

  get errorText() : string {
    const formControl = <FormControl>this.ngForm.form.get(this.for);
    return (formControl.errors) ? JSON.stringify(formControl.errors) : "[no error]";
  }
}

But the NgForm only seems to be injected for Template Forms. Is there an equivalent provider for Reactive Forms that gives access to the enclosing FormGroup?


Solution

  • Instead of injecting ngForm,use the ControlContainer to access FormControls.

    ControlContainer

    A base class for directives that contain multiple registered instances of NgControl.

    @Component({
      selector: 'validation-error',
      template: `{{errorText}}`,
      styles: [`:host { display:block; color:red; }`]
    })
    export class ValidationErrorComponent  {
      @Input() for: string;  // name of input element
      constructor(
         @Optional() private control: ControlContainer
      ) { }
    
      get errorText() : string {
        const formControl = <FormControl>(this.control as any).form.get(this.for);
        return (formControl.errors) ? JSON.stringify(formControl.errors) : "[no error]";
      }
    }
    

    Example