mat-error not showing up with ControlValueAccessor

290 views Asked by At

I have a custom app-input component which uses mat-form-field and mat-error but the error is not showing up.

Am I assigning the NgControl to the formfield the right way?

component

import { Component, OnInit, Input, forwardRef, HostListener, Self, Optional, AfterViewInit } from '@angular/core';
import { ControlValueAccessor, FormControl, FormGroup, FormGroupDirective, NgControl, NgForm, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
import { MatFormFieldAppearance, MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
import { distinctUntilChanged } from 'rxjs/operators';

@Component({
  selector: 'app-input',
  templateUrl: './input.component.html',
  styleUrls: ['./input.component.scss'],
   
})
export class InputComponent implements OnInit, ControlValueAccessor {

  public formField: FormControl = new FormControl('');

  @Input()
  public label: string;

  public value: string;

  public onChanged: (value: string) => void;

  public onTouched: () => void;

  public isDisabled: boolean = false;

  public appearance: MatFormFieldAppearance = this.isDisabled ? 'outline' : 'standard';
  
  constructor(@Optional() @Self() public ngControl: NgControl) {
    if (this.ngControl != null) {
      this.ngControl.valueAccessor = this;
    }
  }

  ngOnInit() {
    const validators = this.ngControl?.control?.validator;

    console.info('validators');
    console.info(validators);
    console.info(validators ? validators : null);

    this.formField.setValidators(validators ? validators : null);
    this.formField.updateValueAndValidity();
  }

  
  writeValue(value: string): void {
    this.value = value;

    this.formField.patchValue(value);
  }

  public onChange (event: Event): void {
    const value: string = 
    (<HTMLInputElement>event.target).value;
    this.onChanged(value);
  }

  registerOnChange(fn: any): void {
    this.onChanged = fn;
  }
  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    this.isDisabled = isDisabled;

    console.info('this.isDisabled');
    console.info(this.isDisabled);

    if (this.isDisabled) {
      this.appearance = "outline";
      this.formField.reset({value: this.formField.value, disabled: true})
    } else {
      this.appearance = "standard";
      this.formField.reset({value: this.formField.value, disabled: false})
    }
  }
}

template

<mat-form-field [appearance]="appearance" class="example-full-width">
    <mat-label>
      {{label}}
    </mat-label>
    <input type="text" matInput 
      autocomplete="off"
      [value]="value" 
      isDisabled="true"
      (input)="onChange($event)" 
      (blur)="onTouched()"
      [formControl]="formField">
    <mat-error *ngIf="formField.errors?.required">
      This field is <strong>required</strong>
    </mat-error>
    <mat-error *ngIf="formField.errors?.email">
      This email is <strong>not valid</strong>
    </mat-error>
  </mat-form-field>
</div>
0

There are 0 answers