Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to initialise a FormGroup in Reactive forms?

Using Angular 11 with Typescript 4 in Strict Mode I have:

export class ContactComponent implements OnInit { 

  form: FormGroup;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {

    this.form = this.formBuilder.group({ 
      email: ['', [Validators.required, Validators.email]],
      name: ['', [Validators.required, Validators.maxLength(40)]],
    });

  }

I get the build error:

 Property 'form' has no initialiser and is not definitely assigned in the constructor.

Shouldn't the FormGroup be initialised on ngOnInit?

like image 629
Miguel Moura Avatar asked Mar 12 '21 16:03

Miguel Moura


1 Answers

Shouldn't the FormGroup be initialised on ngOnInit?

It doesn't have to be; I find it simplest to initialize most things directly on the class like this:

export class ContactComponent implements OnInit { 

  form = this.formBuilder.group({ 
    email: ['', [Validators.required, Validators.email]],
    name:  ['', [Validators.required, Validators.maxLength(40)]],
  });

  constructor(private formBuilder: FormBuilder) { }

}

This works fine with strictPropertyInitialization.

The exception is when initializing something that requires data from the DOM (@Input, @ViewChild, etc) Since those things get initialized in the various Lifecycle Hooks as described in this answer:

  • @Input()ngOnInit
  • @ViewChild()ngAfterViewInit
  • @ContentChildren()ngAfterContentInit

Initializing something that depends on say, an @Input(), would be done in the corresponding lifecycle hook, ngOnInit, however, this does not appease the strict rule, so the Definite Assignment Assertion Operator ! is needed.

export class ContactComponent implements OnInit { 
  @Input() input!: number;

  inputDoubled!: number;
  
  form = this.formBuilder.group({ 
    email: ['', [Validators.required, Validators.email]],
    name:  ['', [Validators.required, Validators.maxLength(40)]],
  });

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.inputDoubled = this.input * 2;
  }
}
like image 95
BizzyBob Avatar answered Sep 25 '22 13:09

BizzyBob