1

I created a custom control which implements ControlValueAccessor and put that control into a template-driven angular form.

That's a form which allows to set start and stop dates for some activity to plan it and the start date in the past isn't valid. I have a validator for that so it shows an error when I click on that control. But when user opens a page he/she doesn't see any errors instantly because the user needs to click on that control to set it in the focused state.

I wanna do the "simple" thing - just automatically focus the control when the date in the past to get this control showing the error. The problem I encountered is that ngAfterViewInit in the parent component is called before writeValue() in the control. So I can set focus but there is no any errors shown. If I click manually on the other field ad then back - I see the error. The problem can be solved by wrapping my code for setting the focused state in a function and passing to setTimeout with zero interval.

That's not the first time I meet the problem like that when ngAfterViewInit is called too early but there is no controllable/synchronous way to make any operation later.

Is there any way to avoid setTimeout in ngAfterViewInit?

Here is the small example without setTimeout which shows that writeValue is called after ngAfterViewInit: https://stackblitz.com/edit/angular-ngafterviewinit-quirks

Thanks in advance!

Maxim Palenov
  • 650
  • 7
  • 17

1 Answers1

0

I think the "simple" thing would be to call updateValueAndValidity not just focus it. Be sure to call it in ngAfterViewChecked

<custom-control name="custom" [(ngModel)]="model.custom" minlength="100"></custom-control>

ngAfterViewChecked(): void {
    this.formRef.form.controls['custom'].updateValueAndValidity();
    console.log(this.formRef.form.controls['custom'].valid);
  }

There is another solution if you don't want to have a reference to the control in the parent explained here in another SO question: setValidators in custom control without from reference in Angular

CornelC
  • 4,974
  • 1
  • 21
  • 28