I'm struggling with some strange behavior while using my custom input component. First of all, I built a simple abstract class that has the main "features" and methods of the component, then, the input-component which has very few code: // Abstract class export abstract class BaseFormInput<T> implements ControlValueAccessor, Validator, AfterViewInit, OnDestroy { @Input() label: string @Output() onChange: EventEmitter<T> = new EventEmitter<T>() private changeInternal: (obj: T) => void private changeSub: Subscription private disabled$ = new BehaviorSubject(false) private required$ = new BehaviorSubject(false) public input = new FormControl(null) ngOnDestroy() { this.changeSub.unsubscribe() } ngAfterViewInit() { this.changeSub = this.input.valueChanges.subscribe(v => { if (!this.disabled$.getValue()) { this.onChange.emit(v) this.changeInternal(v) } }) } writeValue = (obj: T) => this.input.setValue(obj) registerOnChange = (fn: (obj: T) => void) => this.changeInternal = fn registerOnTouched = (_fn: (obj: any) => void) => {} setDisabledState = (isDisabled: boolean) => this.disabled$.next(isDisabled) validate(control: AbstractControl): ValidationErrors { this.required$.next(control.hasValidator(Validators.required)) // THIS LINE HAS WEIRD BEHAVIOR console.log(control, control.errors) return null } public get isDisabled$(){ return this.disabled$.asObservable() } public get isRequired$(){ return this.required$.asObservable() } } The input component is simply designed like this: @Component({ selector: "ec-input-text", template: `<div class="form-control"> <label *ngIf="label"> {{ label }} <span *ngIf="isRequired$ | async">*</span> </label> <input *ngIf="type !== 'textarea'" [type]="type" [formControl]="input" [attr.disabled]="isDisabled$ | async" /> <textarea *ngIf="type === 'textarea'" [formControl]="input" [attr.disabled]="isDisabled$ | async"></textarea> <ng-template></ng-template> </div>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputTextComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => InputTextComponent), multi: true } ] }) export class InputTextComponent extends BaseFormInput<string> { @Input() type: "text" | "password" | "email" | "textarea" = "text" @Input() maxLength: number } Finally, I created a register-component, which uses the input. HTML: <form [formGroup]="form"> <ec-input-text label="First name" formControlName="firstName" /> <ec-input-text label="Last name" formControlName="lastName" /> <ec-input-text label="E-mail" formControlName="email" type="email" /> <ec-input-text label="Password" formControlName="password" type="password" /> </form> The TS of the register-component has a public property like this: public form = new FormGroup({ firstName: new FormControl(null, [Validators.required, Validators.maxLength(50)]), lastName: new FormControl(null, [Validators.required, Validators.maxLength(50)]), email: new FormControl(null, [Validators.required, Validators.maxLength(100)]), password: new FormControl(null, Validators.required) }) Now, the issue is the following: in the validate method of the abstract class (where I put a comment), I tried to log the control errors, and I get a strange behavior: when logging the formControl, I can see in the console that the property errors is null, but if I log control.errors it logs: { required: true } Even though the control is valid and I typed the value (in fact, control.value has a value and results valid). So if i do: console.log(control) And I expand it, errors is null (expected behavior, correct!) But if I do: console.log(control.errors) It is valorized (not correct, the control is valid!) How can I figure this out? Thanks in advance! Continue reading...