David Findlay
David Findlay

Reputation: 1356

What's the proper way to do a FormGroup with FormBuilder in Typescript 4.7+?

In the past we'd do this:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  nameForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.createForm();
  }

  createForm() {
    this.nameForm = this.fb.group({
      surname: '',
      first_name: ''
    });
  }
}

But in TypeScript 4.7+ you get this error:

error TS2564: Property 'nameForm' has no initializer and is not definitely assigned in the constructor.

I could disable "strictpropertyinitilization" in tsconfig.json, or I could declare nameForm as FormGroup | undefined. Neither of those are good options. I could put the formbuilder in the constructor, but we're not supposed to put that stuff in constructors.

So what's the proper Angular Typescript way to do this going forward?

Upvotes: 0

Views: 367

Answers (3)

Telman
Telman

Reputation: 1477

I think the easiest way is to do it during property initialization:

export class AppComponent implements OnInit {
  /* at this point `fb` is already injected and can be used */
  nameForm = this.fb.group({
    surname: '',
    first_name: ''
  });

  constructor(private fb: FormBuilder) {}
}

Other options that you have:

/* just suppress the TS validation with `!` because you know that it's can not be undefined */
nameForm!: FormGroup;

/* make it explicit FormGroup or undefined */
nameForm: FormGroup | undefined;

/* do set up in constructor, then TS will not throw an error */
constructor(private fb: FormBuilder) {
  nameForm = this.fb.group({
    surname: '',
    first_name: ''
  });
}

Upvotes: 1

Théophile Wallez
Théophile Wallez

Reputation: 491

According to the Angular documentation, the correct way of creating a FormGroup is by doing this:

export class ProfileEditorComponent {
  profileForm = new FormGroup({
    firstName: new FormControl(''),
    lastName: new FormControl(''),
  });
}

If you want to use a formBuilder, you need to declare your formGroup like this:

nameForm!: FormGroup;

or:

export class AppComponent { 
   title = 'app'; 
   exampleForm = new FormGroup ({ firstName: new FormControl(), lastName: new FormControl()});

   constructor(private formBuilder: FormBuilder) {
     this.createForm();
   }

   createForm() {
     this.exampleForm = this.formBuilder.group({
       firstName: '',
       lastName: ''
     });
   }
}

Upvotes: 1

Afif Alfiano
Afif Alfiano

Reputation: 309

I think we can use something like this to solve the problem.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  nameForm!: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.createForm();
  }

  createForm() {
    this.nameForm = this.fb.group({
      surname: [''],
      first_name: ['']
    });
  }
}

Upvotes: 1

Related Questions