0

I am creating a reusable text component with validator

export class CompInputComponent implements OnInit{
  @Input() controlFormGroup: FormGroup;
  @Input() controlLabel: string;
  @Input() controlPlaceHolder: string;
  @Input() controlName: string;
  @Input() errorMessage: string;
  private _isRequired = false;

  @Input()
  get isRequired(): boolean {
    return this._isRequired;
  }
  set isRequired(val: boolean) {
    this._isRequired = coerceBooleanProperty(val);
  }

  @Output() onComponentReady: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();
  
  constructor(private fb: FormBuilder) { }
  
  ngOnInit(){
    console.log(this.isRequired);
    if(this.isRequired){
      console.log(this.isRequired);

      this.controlFormGroup.addControl(this.controlName, new FormControl('', Validators.required));
    }else{
      this.controlFormGroup.addControl(this.controlName, new FormControl(''));
    }

    this.onComponentReady.emit(this.controlFormGroup);
  }
}

<div [formGroup]="controlFormGroup">
    <mat-form-field appearance="outline">
        <mat-label>{{controlLabel}}</mat-label>
        <input matInput [placeholder]="controlPlaceHolder" [formControlName]="controlName" />
        <mat-error *ngIf="controlFormGroup.controls.controlName.hasError('required')">">
            <span [innerHTML]="errorMessage"></span>
        </mat-error>
    </mat-form-field>
</div>

My problem is that I can’t set up the mat-error. I have the following error:

core.js:5967 ERROR TypeError: Cannot read property 'hasError' of undefined at CompInputComponent_Template

The name of the control is not hard but also dynamic

1 Answer 1

1

this should work, you are creating your form controls dynamically, it means they doesn't exist at the beginning. you need to check if the form control created.

   export class CompInputComponent implements OnInit{
      @Input() controlFormGroup: FormGroup;
      @Input() controlLabel: string;
      @Input() controlPlaceHolder: string;
      @Input() controlName: string;
      @Input() errorMessage: string;
      private _isRequired = false;
    
      @Input()
      get isRequired(): boolean {
        return this._isRequired;
      }
      set isRequired(val: boolean) {
        this._isRequired = coerceBooleanProperty(val);
      }
    
      @Output() onComponentReady: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();
      
      constructor(private fb: FormBuilder) { }
      
      ngOnInit(){
        console.log(this.isRequired);
        if(this.isRequired){
          console.log(this.isRequired);
    
          this.controlFormGroup.addControl(this.controlName, new FormControl('', Validators.required));
        }else{
          this.controlFormGroup.addControl(this.controlName, new FormControl(''));
        }
    
        this.onComponentReady.emit(this.controlFormGroup);
      }
    }
    
    <div [formGroup]="controlFormGroup">
        <mat-form-field appearance="outline">
            <mat-label>{{controlLabel}}</mat-label>
            <input matInput [placeholder]="controlPlaceHolder" [formControlName]="controlName" />
            <mat-error *ngIf="!!controlFormGroup.controls.controlName && controlFormGroup.controls.controlName.hasError('required')">">
                <span [innerHTML]="errorMessage"></span>
            </mat-error>
        </mat-form-field>
    </div>
Sign up to request clarification or add additional context in comments.

3 Comments

This compiles but when my input is invalid at the time of sending the message does not display in mat-error
well it seams controls of controlFormGroup is missing. be sure if the control name exist. and try this way. *ngIf="controlFormGroup.controls[controlName].errors
Thanks it works perfectly when I click on the field and then I go out

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.