I'm having trouble with being able to subscribe to valueChanges of a form that uses FormArray inside of FormGroup. Essentially, I need to know the value of one input as that changes the validation rules of another. Below is an example of how I have successfully implemented the same concept with a FormBuilder group:
myForm = this.fb.group({
myFirstField: ['', Validators.required],
mySecondField: ['']
});
constructor(
private fb: FormBuilder
) { }
ngOnInit(): void {
this.myForm.get('myFirstField').valueChanges.subscribe(myFirstFieldVal => {
if (myFirstFieldVal === 'something') {
this.myForm.controls.mySecondField.setValidators([Validators.required]);
} else {
this.myForm.controls.mySecondField.clearValidators();
}
this.myForm.controls.mySecondField.updateValueAndValidity();
});
}
And beneath is my attempt at using the same concept with a FormArray. The form itself works in the template with outputting the data and submitting etc. but I need to add some conditional validation within each array. Below is not doing the trick. Any ideas how I can subscribe to the valueChanges of certain fields in each group?
import { Component, OnInit, Input } from '@angular/core';
import { AbstractControl, FormArray, FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
import { BehaviorSubject } from 'rxjs';
export interface ExampleGroup {
myFirstField: string;
mySecondField: string;
}
export class ExampleFormComponent implements OnInit {
dataSource = new BehaviorSubject < AbstractControl[] > ([]);
myFormArr: FormArray = this.fb.array([]);
myFormGroups: FormGroup = this.fb.group({
exampleGroups: this.myFormArr
});
exampleData = [{
myFirstField: 'something',
mySecondField: 'something else',
}, {
myFirstField: 'blah',
mySecondField: '',
}, ];
constructor(private fb: FormBuilder, ) {}
ngOnInit(): void {
// doesn't work
this.myFormArr.controls.forEach((control, index) => {
control.get('myFirstField').valueChanges.subscribe(myFirstFieldVal => {
console.log(control); // doesn't even get to here
if (myFirstFieldVal === 'something') {
this.myFormArr.controls.mySecondField.setValidators([Validators.required]);
} else {
this.myFormArr.controls.mySecondField.clearValidators();
}
this.myForm.controls.mySecondField.updateValueAndValidity();
});
});
this.exampleData.forEach((d: ExampleGroup) => this.addToMyFormArr(d, false));
}
addToMyFormArr(d ? : ExampleGroup) {
const groupToAdd = this.fb.group({
myFirstField: [
d && d.myFirstField ? d.myFirstField : '',
Validators.required, []
],
mySecondField: [d && d.mySecondField ? d.mySecondField : '', []],
});
this.myFormArr.push(groupToAdd);
}
}
This issue was occurring because in my code the forEach
subscribe was being called after addToMyFormArr()
unlike in the code example I provided in the question. I have updated the code example to reflect how the issue was occurring.