简体   繁体   中英

Populating Angular Reactive Forms correcctly

In an angular 7 app, I have created a list of managers. When a user clicks on an item, a view with a populated form should be displayed where the user can then update the manager details. While my view is shown, the manager details doesn't show in the form itself and I can see two errors in the console

ERROR Error: formGroup expects a FormGroup instance. Please pass one in.

ERROR TypeError: Cannot read property 'firstname' of null at ManagerViewComponent.push../src/app/manager/manager-view/manager-view.component.ts.ManagerViewComponent.initForm

This is what my code looks like at the moment.

.ts

import { FormGroup, FormControl } from "@angular/forms";
import { ManagerService } from "./../../services/manager.service";
import { ActivatedRoute, Router } from "@angular/router";
import { Component, OnInit } from "@angular/core";

@Component({
  selector: "app-manager-view",
  templateUrl: "./manager-view.component.html",
  styleUrls: ["./manager-view.component.css"]
})
export class ManagerViewComponent implements OnInit {
  editManagerForm: FormGroup;
  manager = null;

  constructor(
    private route: ActivatedRoute,
    private managerService: ManagerService
  ) {}

  ngOnInit() {
    this.managerDetails();
    this.initForm();
  }

  private initForm() {
    let firstname = this.manager.firstname;
    let lastname = this.manager.lastname;
    let username = this.manager.username;
    let password = this.manager.password;
    let terminal = this.manager.terminal.name;

    this.editManagerForm = new FormGroup({
      firstname: new FormControl(firstname),
      lastname: new FormControl(lastname),
      username: new FormControl(username),
      password: new FormControl(password),
      terminal: new FormControl(terminal)
    });
  }

  managerDetails() {
    const managerId = this.route.snapshot.paramMap.get("id");

    this.managerService.getManager(managerId).then(data => {
      this.manager = data;
    });
  }

.html

<form id="editManager" [formGroup]="editManagerForm">
  <div class="form-row">
    <div class="col-6 form-group">
        <label for="">Firstname</label>
        <input
        formControlName="firstname"
        type="text"
        class="form-control"
        />
    </div>

    <div class="col-6 form-group">
        <label for="">Lastname</label>
        <input
        formControlName="lastname"
        type="text"
        class="form-control"
        />
    </div>
  </div>

  <div class="form-row">
    <div class="col-6 form-group">
        <label for="terminal">Bus Terminal</label>
        <select formControlName="terminal" class="form-control">
        <option selected>{{ manager.terminal.name }}</option>
        <option *ngFor="let terminal of terminals" [ngValue]="terminal">
            {{ terminal.name }}
        </option>
        </select>
    </div>
  </div>

  <!-- <p>{{ editManagerForm.value | json }}</p> -->
</form>

In app.module.ts I have both FormsModule and ReactiveFormsModule imported correcctly like this

import { FormsModule, ReactiveFormsModule } from "@angular/forms";

Apparently I am doing something wrong since this is my first attempt at populating reactive forms. Please help me fix this

You will need to make the following changes when you initialise your editManagerForm. You should use a FormBuilder to generate your Form Group and Form Controls.

Do remember to import formBuilder and formGroup on your component.

import { FormBuilder, FormGroup } from '@angular/forms';
.
.
constructor(
  private formBuilder: FormBuilder,
) { }

editManagerForm: FormGroup = this.formBuilder.group({
    firstName: [null],
    lastName: [null],
    username: [null],
    password: [null],
    terminal: [null],
}

I assume you will populate the editManagerForm on the managerDetails() method. You can achieve this by using patchValue :

managerDetails() {
  const managerId = this.route.snapshot.paramMap.get("id");

  this.managerService.getManager(managerId).then(data => {
    this.editManagerForm.patchValue(data);
  });
}

Note: I am assuming that the data you fetched from getManager() is an object in the following format

data = {
  firstName: '',
  lastName: '',
  username: '',
  password: '',
  terminal: ''
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM