Pre Populate input field in `FormGroup` - Angular2

16,810

UPDATE: As we found out, you are needing a formArray instead of a single formControl. So declare that when you build form:

this.queryForm = this.fb.group({
  arrayOfData: this.fb.array([]) // name a proper name to array
})

You can use setValue or patchValue when you have received your data, where you iterate the response and patch the values to your form array. Call patchValues-method in your callback (subscribe).

patchValues() {
  const control = <FormArray>this.queryForm.get('arrayOfData');
  this.items.forEach(x => {
    control.push(this.patchValue(x.first_name, x.pcode))
  })
}

patchValue(name, code) {
  return this.fb.group({
    name: [name],
    pcode: [code]
  })    
}

In your template iterate the formarray and also remember to set the formgroupname (which is the index):

<div formArrayName="arrayOfData">
  <div *ngFor="let code of queryForm.get('arrayOFData').controls; let i = index">
    <div [formGroupName]="i">
      <label>Name: </label>
      <input formControlName="name" /><br>
      <label>Product Code: </label>
      <input formControlName="pcode" /><br>
    </div>
  </div>
</div>


Original answer:

You should always set the form values in the component, not the template. You can use patchValue or setValue, when you have received the value from the service... so you can do this e.g inside the callback (subscribe):

this.myService.getSomeData()
  .subscribe(data => {
     this.item = data;
     this.queryForm.patchValue({pcode: this.item.productCode})
  });

Then you do not need to use [value]="item.productCode" in your form, this value is set with the form control instead.

Share:
16,810
Gags
Author by

Gags

I am a Web Designer and Developer with still a lot more to learn and skills as PHP Laravel Angular React jQuery HTML 5 Bootstrap MySQL Database

Updated on June 15, 2022

Comments

  • Gags
    Gags almost 2 years

    I am using Angular2 - Reactive Forms. Everything works fine until i want to show a pre-populated value in one of fields in Form.

    Scenario: There are multiple buttons on a page and each button opens up a form with fields as

    1. Name
    2. Email
    3. Message
    4. Product Code --> Value for this shall be prepopulated as per item code from service.

    Failing Scenario: Product Code input value turns to null.

    TS Code:

    import { FormGroup, FormBuilder, Validators } from '@angular/forms';
    queryForm: FormGroup;
    constructor(private _productService: ProductService, fb: FormBuilder) {
        this.queryForm = fb.group({
            'name': [null, Validators.compose([Validators.required, Validators.minLength(5)])],
            'email': [
                null, [Validators.required, Validators.email]
            ],
            'message': [null,Validators.compose([Validators.required, Validators.minLength(5)])],
            'pcode': [
                null
            ],
        })
    }
    

    HTML Form:

    <div *ngFor="let item of product">
    <form action="#" [formGroup]="queryForm" 
     (ngSubmit)="submitForm(queryForm.value)" method="post" 
      novalidate="" class="text-left note" id="f_{{item.productId}}">
        [ .... rest of the fields ...]
        <div class="form-group hidden">
              <input type="hidden " class="form-control " id="pcode " name="pcode" 
            formControlName="pcode" [value]="item.productCode" />
         </div>
         <div class="form-group">
               <button type="submit" class="btn1" [disabled]="!queryForm.valid">Submit</button>
          </div>
    </form>
    </div>
    

    How can i achieve this?