Home > Software design >  Angular 14 - How to define type for the nested FormGroup in FormBuilder
Angular 14 - How to define type for the nested FormGroup in FormBuilder

Time:11-16

this.form = this.formBuilder.group({
      kWhControl: [false, []],
      kWhValue: [0, []],
      identified: this.formBuilder.group({
        kWhControl: [false, []],
        kWhValue: [0, []],
      }),
)};

Tried multiple ways but coudn't get what exatly is the right way to do this.

CodePudding user response:

If you use FormBuilder to generate forms it accepts object generic to define types. You have to pass all the controls, like this:

this.form = this.formBuilder.group<{
    kWhControl: FormControl<boolean>,
    ...,
    identified: FormGroup<{ 
      kWhControl: FormControl<boolean>,
      kWhValue: FormControl<number>,
    }>,
  }>(
...

You can do some tricks here, if you have repeated structure inside, like this:

type KWhFormGroup = {
  kWhControl: FormControl<boolean>;
  kWhValue: FormControl<number>;
  identified?: FormGroup<KWhFormGroup>;
}

and then:

this.form = this.formBuilder.group<KWhFormGroup>(
...

CodePudding user response:

This helped me to resolve my issue

type NewType<T> = [
            T | { value: T; disabled: boolean },
        (AbstractControlOptions | ValidatorFn | ValidatorFn[])?,
    ]

export type FormGroupConfig<T> = {
    [P in keyof T]: 
       T[P] extends object
            ? FormGroupConfig<T[P]>
            : NewType<T[P]>;

}

CodePudding user response:

Thank you for the answer, 
Yeah I have tried that, but I was thinking of having a cleaned interface in place to define my form type and a generic FormGroupModel, anyway the below snippet helped me to do that, and now my form looks so clean and understandable, here is my implementation: 

interface VehicleBasedControlsForm {
  kWhControl: boolean;
  kWhValue: number;
  identified: {
    kWhControl: boolean;
    kWhValue: number;
  }
}

===Generic FormModel===
type FormGroupModel<T> = FormGroup<{
  [K in keyof T]: T[K] extends object
    ? FormGroupModel<T[K]>
    : ɵElement<T[K], null>;
}>;

Use it like FormGroupModel<VehicleBasedControlsForm>

  • Related