Gubasek Duzy
Gubasek Duzy

Reputation: 60

How to set option in select using formGroup in angular?

I have simple web app (crud), when I can save data to my database. In moment when I want to edit existing collection in my DB data should to load into edit window for better working of my site. I menaged to load data to simple <input type='text'> and to <input type='nubmer'>, but in case when I want to load data to <select> this is not working. In option of my select there are data from DB and it works fine.

I have one problem, when I click edit button only person_name doesnt load to <select>

HTML:

<div class="card">
  <div class="card-body">
    <form [formGroup]="expenForm" novalidate>
      <div class="form-group">
        <label class="col-md-4"> Person Name</label>
        <select class="form-control" formControlName="person_name" #person_name>
          <option *ngFor="let person of people">
            {{ person.person_name }}
          </option>
        </select>
      </div>

      <div class="form-group">
        <label class="col-md-4"> Amount</label>
        <input
          type="number"
          class=" form-control"
          min="0"
          formControlName="amount"
          #amount
        />
      </div>

      <div class="form-group">
        <label class="col-md-4"> Description</label>
        <input
          class="form-control"
          formControlName="description"
          #description
          maxlength="100"
        />
      </div>
      <div class="form-group">
        <button
          (click)="
            updateExpen(person_name.value, amount.value, description.value)
          "
          class="btn btn-primary"
        >
          Submit expen
        </button>
      </div>
    </form>
  </div>
</div>

TS:

import { Component, OnInit, Input } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import {
  FormGroup,
  FormBuilder,
  Validators,
  FormControl
} from "@angular/forms";
import { ExpenService } from "../expen.service";
import Expen from "../Expen";

@Component({
  selector: "app-edit-expen",
  templateUrl: "./edit-expen.component.html",
  styleUrls: ["./edit-expen.component.scss"]
})
export class EditExpenComponent implements OnInit {
  @Input() displayText: String;

  expen: any = {};
  expenForm: FormGroup;
  public people: Expen[];

  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private fb: FormBuilder,
    private es: ExpenService
  ) {
    this.createForm();
  }

  createForm() {
    this.expenForm = this.fb.group({
      person_name: ['', Validators.required],
      amount: [this.expen.amount, Validators.required],
      description: [this.expen.description, Validators.required]
    });
  }

  updateExpen(person_name, amount, description) {
    this.route.params.subscribe(params => {
      this.es.updateExpen(person_name, amount, description, params["id"]);
      this.router.navigate(["/expen"]);
    });
  }
  ngOnInit() {
    this.route.params.subscribe(params => {
      this.es.editExpen(params["id"]).subscribe(res => {
        this.expen = res;
      });
    });

    this.es.getAllPeople().subscribe((data: Expen[]) => {
      this.people = data;
    });

    this.createForm();
  }
}

I tried with: person_name: [this.expen.person_name, Validators.required], expenForm=new FormGroup({person_nam: new FormControl(this.expen.person_name)});

But it doesn't work. Do you have any idea to solve this problem?

Upvotes: 1

Views: 19565

Answers (2)

AVJT82
AVJT82

Reputation: 73357

Create the form as empty in constructor:

createForm() {
  this.expenForm = this.fb.group({
    person_name: ['', Validators.required],
    amount: ['', Validators.required],
    description: ['', Validators.required]
  });
}

Add [value] to your option, and use setValue or patchValue when you have the values, since this is asynchronous

<option *ngFor="let person of people" [value]="person.person_name">

TS:

this.es.editExpen(params["id"]).subscribe(res => {
  this.expen = res;
  this.expenForm.setValue({
    person_name: this.expen.person_name,
    amount: this.expen.amount
    description: this.expen.description
  });
});

Or if you know that your object matches the form structure, you can also use:

this.expenForm.setValue(this.expen)

Also remove createForm from OnInit, you already have it in the constructor.

Upvotes: 5

SGalea
SGalea

Reputation: 722

Update your view and your form builder definition

<select class="form-control" formControlName="person_name" [value]="expen.person_name" #person_name>
  <option *ngFor="let person of persons">
    {{ person.person_name }}
  </option>
</select>

this.expenForm = this.fb.group({
  person_name: [this.expen.person_name, Validators.required],
  amount: [this.expen.amount, Validators.required],
  description: [this.expen.description, Validators.required]
});

Upvotes: 0

Related Questions