dna
dna

Reputation: 626

angular create input component reusable

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

Upvotes: 0

Views: 480

Answers (1)

menethil
menethil

Reputation: 63

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>

Upvotes: 1

Related Questions