Angular Custom FormControl validation

Viewed 153

I am currently trying out the custom form controls of angular. For this i am building a simple example component with a FormGroup with firstName and lastName. Everything works fine so far, but i've got a question. Maybe someone here has a hint for me. I'm binding my "externalControl" in the parent component with the following code:

form = new FormGroup({
  name: new FormControl(null, Validators.required);
});

<div [formGroup]="form">
    <name-input [formControl]="form.get('name')"></name-input>
</div>

As you can see my parent form has a required validator. So in my custom form control i want to check, whether my parent form has a given validator and if it is valid. Here i am struggling a little bit. I am currently using the build in angular function "validate()" to get the "externalControl" and bind it in my custom-form-control. This may be bad practice, but i did not find any other way to check whether my parent-form has validation errors.

The code of my custom form control:

@Component({
  selector: 'name-input',
  templateUrl: './name-input.component.html',
  styleUrls: ['./name-input.component.scss'],
  // changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      multi: true,
      useExisting: NameInputComponent
    },
    {
      provide: NG_VALIDATORS,
      multi: true,
      useExisting: NameInputComponent
    }
  ]
})
export class NameInputComponent implements ControlValueAccessor, Validator {
  form: FormGroup;
  externalControl: AbstractControl;

  constructor() {
    this.initForm();
  }


  /** `View -> model callback called when value changes` */
  _onChange: (value: any) => void = () => {
  }

  /** `View -> model callback called when select has been touched` */
  _onTouched = () => {
  }

  change(value: string): void {
    this._onChange(value);
    this._onTouched();
  }

  validate(ctrl: AbstractControl): any {
    // TODO: Is this really okay?
    this.externalControl = ctrl;
    console.log(this.externalControl.errors);
  }

  /**
   * @description
   * Method of ControlValueAccessor -> Allows Angular to update the model (value). The valueChanged event should always be emitted
   * if the current value is changing. This applies to changes from outside and from direct user interactions.
   */
  writeValue(value: any): void {
    if (value) {
      this.form.setValue(value, {emitEvent: false});
    }
  }

  /**
   * @description
   * Method of ControlValueAccessor -> Allows Angular to register a function to call when the model (value) changes.
   * The forms api is passing us the function, which it wants us to call.
   */
  registerOnChange(fn: (value: any) => void): void {
    this._onChange = fn;
    this.form.valueChanges.subscribe(fn);
  }

  /**
   * @description
   * Method of ControlValueAccessor -> Allows Angular to register a function to call when the input has been touched.
   */
  registerOnTouched(fn: () => void): void {
    this._onTouched = fn;
  }

  /**
   * @description
   * Method of ControlValueAccessor -> Allows Angular to disable the input.
   */
  setDisabledState(isDisabled: boolean): void {
    isDisabled ? this.form.disable() : this.form.enable();
  }

  private initForm(): void {
    this.form = new FormGroup({
      firstName: new FormControl(),
      lastName: new FormControl()
    });
  }
}
0 Answers
Related