Home > Mobile >  Join two reactive forms
Join two reactive forms

Time:10-24

I have an angular reactive form that I want to add a form group from a the different file. I can't get it to work. I have a function that return an untyped form group:

public getEmptyTemplateForm(): FormGroup {
    const template = new FormGroup({
      'id': this.formBuilder.nonNullable.control<number>(0),
      'name': this.formBuilder.nonNullable.control<string>(''),
      'expirationType': this.formBuilder.nonNullable.control<number | string> (
        '', [Validators.required, Validators.pattern('^[0-9]*$')],
      ),
      'expirationDate': this.formBuilder.nonNullable.control(
        this.moment(new Date()), []
      ),
      'expirationDays': this.formBuilder.nonNullable.control<number | string> (
        '', [Validators.pattern('^[0-9]*$')],
      ),
      'serverCount': this.formBuilder.nonNullable.control<number | string> (
        '', [Validators.required, Validators.pattern('^[0-9]*$')]
      ),
      'appCount': this.formBuilder.nonNullable.control<number | string> (
        '', [Validators.required, Validators.pattern('^[0-9]*$')]
      ),
      'featuresList': this.formBuilder.array<number>([]),
    });
    return template;
  }

And the main form:

licenseForm = this.fb.group({
    id: this.fb.nonNullable.control<number | undefined>(undefined),
    activationKey: ['', [Validators.required]],
    enabled: [true],
    customerId: this.fb.nonNullable.control<number | undefined>(undefined),
    customerName: ['', [Validators.required]],
    // template: this.fb.nonNullable.group<Partial<Template>>({}),
    hostId: [''],
    licenseText: [''],
  });

And than tried to put the following code in either the constructor or ngOnInit:

const emptyTemplateForm = this.emptyTemplateFormService.getEmptyTemplateForm();
this.licenseForm.addControl("template", emptyTemplateForm)

Using setControl give the this error:

Error: Cannot find control with path: 'template -> id' (etc.)

and addControl gives the following error:

No overload matches this call. Overload 1 of 2, '(this: FormGroup<{ [key: string]: AbstractControl<any, any>; }>, name: string, control: AbstractControl<any, any>, options?: { emitEvent?: boolean | undefined; } | undefined): void', gave the following error. The 'this' context of type 'FormGroup<{ id: FormControl<number | undefined>; activationKey: FormControl<string | null>; enabled: FormControl<boolean | null>; customerId: FormControl<...>; customerName: FormControl<...>; hostId: FormControl<...>; licenseText: FormControl<...>; }>' is not assignable to method's 'this' of type 'FormGroup<{ [key: string]: AbstractControl<any, any>; }>'. Type '{ [key: string]: AbstractControl<any, any>; }' is missing the following properties from type '{ id: FormControl<number | undefined>; activationKey: FormControl<string | null>; enabled: FormControl<boolean | null>; customerId: FormControl<...>; customerName: FormControl<...>; hostId: FormControl<...>; licenseText: FormControl<...>; }': id, activationKey, enabled, customerId, and 3 more. Overload 2 of 2, '(name: "id" | "activationKey" | "enabled" | "customerId" | "customerName" | "hostId" | "licenseText", control: FormControl<number | undefined> | FormControl<string | null> | FormControl<...>, options?: { ...; } | undefined): void', gave the following error. Argument of type '"template"' is not assignable to parameter of type '"id" | "activationKey" | "enabled" | "customerId" | "customerName" | "hostId" | "licenseText"'.

The HTML:

//Main component
    <div formGroupName="template" >
      <div >
        <label for="templateId">Template:</label>
        <select
          
          formControlName="id"
          (change)="changeTemplate()"
        >
          <option
            *ngFor="let template of templates"
            [ngValue]="template.id"
          >
            {{ template.name }}
          </option>
        </select>
      </div>
      <app-license-restrictions-fields groupName="template"></app-license-restrictions-fields>
    </div>

// Template component
<form autocomplete="off" [formGroup]="template">
    <div>
      <label for="serverCount">Max. Servers:</label>
      <input
        type="number"
        formControlName="serverCount"
        id="serverCount"
      >
    </div>
    <div>
      <label for="appCount">Max. Applications:</label>
      <input
        type="number"
        formControlName="appCount"
        id="appCount"
      >
    </div>
    <div >
      <label for="expirationType">Expiration Type:</label>
      <mat-button-toggle-group
        formControlName="expirationType"
        id="expirationType"
      >
        <mat-button-toggle [value]="0" >Date</mat-button-toggle>
        <mat-button-toggle [value]="1" >Days</mat-button-toggle>
      </mat-button-toggle-group>
    </div>
    <section *ngIf="template.get('expirationType')?.value === 0">
      <label for="expirationDate" >Expiration Date:</label>
      <mat-form-field >
        <input
          matInput
          [matDatepicker]="picker"
          formControlName="expirationDate"
          id="expirationDate"
          name="expirationDate"
          (dateChange)="updateExpirationDays()"
        >
        <mat-hint>MM/DD/YYYY</mat-hint>
        <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
        <mat-datepicker #picker></mat-datepicker>
      </mat-form-field>
    </section>
    <div *ngIf="template.get('expirationType')?.value === 1" >
      <label for="expirationDays">Days To Expiration:</label>
      <input
        type="number"
        formControlName="expirationDays"
        id="expirationDays"
        (change)="updateExpirationDate()"
      >
    </div>
    <app-feature-list [features]="features" (selectFeature)="onSelectFeature($event)"></app-feature-list>
  </form>

Please, How can I make it to work?

CodePudding user response:

Try this

 licenseForm!: FormGroup;
  constructor(
    private fb: FormBuilder,
    private formTemplateService: FormTemplateService
  ) {}

  ngOnInit(): void {
    this.createLicenseForm();
  }

  createLicenseForm = () => {
    this.licenseForm = this.fb.group({
      // ...
      template: this.formTemplateService.getTemplateFormGroup(),
      // ...
    });
  }

Stackblitz Link: https://stackblitz.com/edit/codeandcloud-so-74178980

  • Related