nested-forms/apps/baseline
Kevin C. Coram f99b91a77e
Document Base Line application
2019-12-31 11:25:49 -08:00
..
src Remove un-used `contact` attribute 2019-12-31 11:05:04 -08:00
README.md Document Base Line application 2019-12-31 11:25:49 -08:00
browserslist Generate baseline application 2019-09-05 23:24:05 -04:00
jest.config.js Generate baseline application 2019-09-05 23:24:05 -04:00
tsconfig.app.json Generate baseline application 2019-09-05 23:24:05 -04:00
tsconfig.json Generate baseline application 2019-09-05 23:24:05 -04:00
tsconfig.spec.json Generate baseline application 2019-09-05 23:24:05 -04:00
tslint.json Generate baseline application 2019-09-05 23:24:05 -04:00

README.md

Base Line - The Single component

The easiest way to create a simple Reactive Form is to use a single Angular component to build and display the form. In this example application, an asynchronous call to an API is simulated. The Contact object thus obtained is used to create and initialize a FormGroup using the Angular FormBuilder.

  public ngOnInit() {
    this.subscription = this.service
      .loadContact()
      .subscribe((data: Contact) => {
        this.form = this.createForm(data);
      });
  }

  public createForm(model: Contact): FormGroup {
    const name = model.name;

    const addresses: FormArray = this.fb.array([]);

    const group = this.fb.group({
      name: this.fb.group({
        firstName: [name ? name.firstName : ''],
        lastName: [name ? name.lastName : ''],
        middleName: [name ? name.middleName : ''],
        prefix: [name ? name.prefix : ''],
        suffix: [name ? name.suffix : ''],
      }),
      addresses: addresses,
    });

    if (model.addresses) {
      model.addresses.forEach(addr => {
        addresses.push(
          this.fb.group({
            line1: [addr ? addr.line1 : ''],
            line2: [addr ? addr.line2 : ''],
            city: [addr ? addr.city : ''],
            state: [addr ? addr.state : ''],
            postalCode: [addr ? addr.postalCode : ''],
          }),
        );
      });
    }

    return group;
  }

  get addresses(): FormArray {
    return this.form.get('addresses') as FormArray;
  }

The component's template remders input controls for the Contact's name, and iterates over the array of addresses to render controls to edit each one.

<form *ngIf="form" [formGroup]="form">
  <ng-container formGroupName="name">
    <div>
      <label for="firstName">First Name: </label>
      <input name="firstName" formControlName="firstName">
    </div>
    <!-- etc for each attribute in the Contact name -->
  </ng-container>

  <ng-container formArrayName="addresses">
    <ng-container *ngFor="let addr of addresses.controls; let i=index">
      <!-- Note: the form group is bound to the index variable -->
      <ng-container [formGroupName]="i">
        <div>
          <label for="line1">Line 1: </label>
          <input name="line1" formControlName="line1">
        </div>
        <!-- etc for each attribute in the Address -->
      </ng-container>
    </ng-container>
  </ng-container>

</form>

Pros

  • All of the logic is in one place
  • The potential complexity of multiple components is avoided

Cons

  • The component and its template will become ever larger and more complex as the form grows
  • Little-to-no opportunity for code reuse