Skip to content

Reactive Form gets wrong path with nested groups when doing it recursivly #48982

Open
@anjunar

Description

@anjunar

Which @angular/* package(s) are the source of the bug?

forms

Is this a regression?

No

Description

The formControlName has as parent the FormControlDirective and not the formGroupName as parent. In this way the 3 Inputs are missing the Form Group "form"

<button type="button" (click)="onClick()">Load</button>
<form [formGroup]="form">
  <ng-container *ngTemplateOutlet="fields; context : {$implicit : schema}"></ng-container>

  <ng-template #fields let-node>
    <ng-container *ngFor="let control of node.properties | keyvalue">
      <ng-container [ngSwitch]="widget(control.value)">
        <ng-container *ngSwitchCase="'form'">
          <div [formGroupName]="key(control)" >
            <ng-container *ngTemplateOutlet="fields; context : {$implicit : control.value}"></ng-container>
          </div>
        </ng-container>
        <ng-container *ngSwitchDefault>
          <input type="text" [formControlName]="key(control)" [placeholder]="key(control)">
        </ng-container>
      </ng-container>
    </ng-container>
  </ng-template>
</form>
{
  "$schema" : {
    "properties" : {
      "form" : {
        "widget" : "form",
        "type" : "object",
        "properties" : {
          "firstName" : {
            "type" : "string",
            "title" : "First Name",
            "widget" : "text"
          },
          "lastName" : {
            "type" : "string",
            "title" : "Last Name",
            "widget" : "text"
          },
          "birthDate" : {
            "type" : "string",
            "title" : "Birthdate",
            "widget" : "date"
          }
        }
      }
    }
  },
  "form" : {
    "firstName" : "Patrick",
    "lastName" : "Bittner",
    "birthDate" : "1980-04-01"
  }
}
import {Component, Input, OnInit, ViewEncapsulation} from '@angular/core';
import {FormBuilder, FormGroup} from "@angular/forms";
import {Node} from "./as-meta-form.classes";

@Component({
  selector: 'as-meta-form',
  templateUrl: 'as-meta-form.component.html',
  styleUrls: ['as-meta-form.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class AsMetaFormComponent implements OnInit {

  @Input() model!: any
  @Input() schema!: Node
  form!: FormGroup

  constructor(private formBuilder: FormBuilder) {
  }

  ngOnInit(): void {
    this.form = this.formBuilder.group(this.schema2Form(this.schema.properties));
  }

  onClick() {
    this.form.setValue({form: this.model.form})
  }

  key(value: any): string {
    return value.key
  }

  widget(value: any): string {
    return value.widget
  }

  schema2Form(properties: any): FormGroup {
    let switchNode = (node: any) => {
      switch (node.widget) {
        case "form" : {
          return this.formBuilder.group(this.schema2Form(node.properties))
        }
        default : {
          return [""]
        }
      }
    }

    return Object.entries(properties).reduce((prev, [key, value]) => {
      prev[key] = switchNode(value);
      return prev;
    }, {} as any)
  }

}

Please provide a link to a minimal reproduction of the bug

Please provide the exception or error you saw

ERROR Error: Cannot find control with name: 'birthDate'
ERROR Error: Cannot find control with name: 'lastName'
ERROR Error: Cannot find control with name: 'firstName'

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 15.1.1
Node: 19.4.0 (Unsupported)
Package Manager: npm 9.2.0
OS: win32 x64

Angular: 15.1.0
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1501.1
@angular-devkit/build-angular   15.1.1
@angular-devkit/core            15.1.1
@angular-devkit/schematics      15.1.1
@angular/cli                    15.1.1
@schematics/angular             15.1.1
ng-packagr                      15.1.1
rxjs                            7.8.0
typescript                      4.9.4

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions