Apple developer
Apple developer

Reputation: 137

Unable to set dynamic input fields ionic

I am new to ionic,

I want to set dynamic input fields to my form, Here is my code but i am unable to set

home.ts

constructor() {
  pData = //Got data from server;
  this.myForm1 = this._fb.group({
    ship_owner_name: [pData.ship_owner_name],
    deck_array: this._fb.array([])
  });
  this.AddItemData(pData.deck_array);
}

AddItemData(item) {
  const arrayControl = < FormArray > this.myForm1.controls['deck_array'];
  let newGroup = this._fb.group({
    selectedDeck: item
  });
  arrayControl.push(newGroup);
}

Server data i have retrived is:

pData = {
  "ship_owner_name": "john smith",
  "deck_array": [
    "MD 1",
    "MD 2"
  ],
}

Code for template home.html

<form [formGroup]="myForm1">
    <ion-list no-lines class="listMargin">
        <ion-item>
          <ion-label class="labelColor" stacked>
            Ship owner name 
          </ion-label>
          <ion-input formControlName="ship_owner_name" type="text"></ion-input>
      </ion-item>
    <div formArrayName="deck_array" style="background-color:white">
        <ion-list *ngFor="let obj of myForm1.controls.deck_array.controls;let i=index">

            <div [formGroupName]="i" >
                    <ion-item no-lines>
                    <ion-input placeholder="select from list or type in"></ion-input>
 </ion-item>

            </div>

        </ion-list>

</div>

</ion-list>

Please help and thanks in advance

Upvotes: 0

Views: 974

Answers (1)

SiddAjmera
SiddAjmera

Reputation: 39432

There are a few issues with your implementation.

For starters, you're making deck_array in the form a FormArray of FormGroups when it should be a FormArray of FormControls

Secondly, you're not going to get the reference of desk_array like this: <FormArray>this.myForm1.controls['deck_array'];

Thirdly, I'm not really sure where you're getting the _fb from if you haven't injected it in your constructor.

Fourth, you should be making your constructor as lean as possible. So all the code to get the data from the server, instantiate the form, and set it's value should go inside ngOnInit.

Fifth, you should be creating a getter in your typescript class that is going to give you the FormArray's controls. Also, you should be using [formControlName] instead of the [formGroupName] directive to bind the form to the view.

I've fixed all these issues on the form and now it works as expected. Here's what I did.

import { Component } from '@angular/core';
import { FormBuilder, FormArray } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  pData;
  myForm1;

  constructor(private _fb: FormBuilder) {}

  ngOnInit() {
    // Suppose that this is obtained by an AJAX Call to the server.
    this.pData = {
      "ship_owner_name": "john smith",
      "deck_array": [
        "MD 1",
        "MD 2"
      ],
    };

    this.myForm1 = this._fb.group({
      ship_owner_name: [this.pData.ship_owner_name],
      deck_array: this._fb.array([])
    });
    this.AddItemData(this.pData.deck_array);
    console.log(this.myForm1.value);
  }

  AddItemData(item) {
    const arrayControl = (<FormArray>this.myForm1.get('deck_array'));
    console.log(this.pData.deck_array);
    const controls = this.pData.deck_array.map(value => this._fb.control(value));
    console.log(controls);
    controls.forEach(control => arrayControl.push(control));
  }

  get controlsArray() {
    return (<FormArray>this.myForm1.get('deck_array')).controls;
  }

}

And then in your template, change:

<ion-list *ngFor="let obj of myForm1.controls.deck_array.controls;let i=index">

to

<ion-list *ngFor="let obj of controlsArray;let i=index">

Here's the full template as you've given:

<form [formGroup]="myForm1">
  <ion-list no-lines class="listMargin">
    <ion-item>
      <ion-label class="labelColor" stacked>
        Ship owner name
      </ion-label>
      <ion-input formControlName="ship_owner_name" type="text"></ion-input>
    </ion-item>
    <div formArrayName="deck_array" style="background-color:white">
      <ion-list *ngFor="let obj of controlsArray;let i=index">
        <div>
          <ion-item no-lines>
            <ion-input 
              [formControlName]="i"
              placeholder="select from list or type in"></ion-input>
          </ion-item>
        </div>
      </ion-list>
    </div>
  </ion-list>

Here's a Sample StackBlitz for your reference.

Upvotes: 1

Related Questions