0

I created a form using ReactiveForms module in Angular 4. In my .ts file:

myForm: FormGroup;
dataTypes: FormArray;

ngOnInit() {
  this.myForm = new FormGroup({});
  this.dataTypes = new FormArray([
      new FormControl("A"),
      new FormControl("B"),
      new FormControl("C")
  ]);
  this.myForm.addControl('dataTypes', this.dataTypes);
}

onSubmit() {
  console.log(this.myForm.value);
}

And in my html:

<form [formGroup]="myForm" (ngSubmit)=onSubmit()>
  <select name="datatypes"
          id="datatypes"
          formArrayName="dataTypes">

          <option *ngFor="let dataType of myForm.get('dataTypes').controls;
                          let dataIndex=index"
                          [ngValue]="dataIndex">
                          {{ dataType.value }}
          </option>
  </select>

  <button type="submit">Submit</button>
</form>

On clicking the submit button, I am trying to console log the value of the form submitted. The form with the drop down list is displayed correctly. The first step is to extract the value of the drop drown list selected by the user. But the console.log gives an array with all the three values and not the value selected. How will the myForm.value have only the selected value of dataTypes on submit?

2 Answers 2

2

@Shiv, not put the "options" in the Form

ngOnInit() {
  this.dataTypes=["A","B","C"] //<--just a variable
  this.myForm = new FormGroup({  //<--your form only have a control dataType
    datatype:""});
}
<form [formGroup]="myForm" (ngSubmit)=onSubmit()>
  <select name="datatype" id="datatype">
         <!--the ngFor of the variable dataTypes-->
          <option *ngFor="let dataType of dataTypes;let dataIndex=index"
              [ngValue]="dataIndex">{{dataType}}
          </option>
  </select>
  <button type="submit">Submit</button>
</form>
Sign up to request clarification or add additional context in comments.

2 Comments

A clever hack. So in general how do you use FormArray with select? Or is it just not done? You have avoided using FormArray altogether above.
@ShivKumar, it's not a hack. you use FormArray if you want a formArray. e.g. if you have a list of check-box, but not in a select. In a select you have only one field
0

you can get the selected value using @ViewChild (doc) and ElementRef (doc)

import {ElementRef, ViewChild} from '@angular/core';

myForm: FormGroup;
dataTypes: FormArray;
@ViewChild('mySelect') mySelect: ElementRef;

ngOnInit() {
  this.myForm = new FormGroup({});
  this.dataTypes = new FormArray([
      new FormControl("A"),
      new FormControl("B"),
      new FormControl("C")
  ]);
  this.myForm.addControl('dataTypes', this.dataTypes);
}

onSubmit() {
  console.log(this.mySelect.nativeElement.value); // here you console the selected value 
  console.log(this.myForm.value);
}

//===

<form [formGroup]="myForm" (ngSubmit)=onSubmit()>
  <select name="datatypes"
          id="datatypes"
          #mySelect
          formArrayName="dataTypes">

          <option *ngFor="let dataType of myForm.get('dataTypes').controls;
                          let dataIndex=index"
                          [ngValue]="dataIndex">
                          {{ dataType.value }}
          </option>
  </select>

  <button type="submit">Submit</button>
</form>

here I kept your code with as little changes as I could.

// ==========

here's without a local reference

has mentioned be Eliseo, you can simply define your select options as variables. insted of FormArray just use one formCtrl and bind it to your select element, in the onSubmit method fetch the value on that formCtrl.

myForm: FormGroup;
selectValues: string[] = ["A","B","C"];
constructor(private formBuilder: FormBuilder) {}

ngOnInit() {
    this.myForm = this.formBuilder.group({
        selectFormCtrl: ''
    });
}

onSubmit() {
      console.log(this.myForm.controls["selectFormCtrl"].value);
}

//==

  <form [formGroup]="myForm" (ngSubmit)=onSubmit()>
    <select formControlName="selectFormCtrl">
      <option *ngFor="let dataType of selectValues;"
              [ngValue]="dataType">
        {{ dataType }}
      </option>
    </select>

    <button type="submit">Submit</button>
  </form>

1 Comment

Wouldn't this kind of defeat the purpose of reactive forms? If I am defining the form in the .ts file shouldn't I be able to use it in the .ts? You are suggesting using a local reference which is usually done with template forms.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.