"stolen" the idea of AT82, we can has a recursive function that return an observable. Well, instead of use "tap", we can use map to return an object with two properties: name (the control has changed) and value.
So some like
mergeForm(form: FormGroup | FormArray, suffix: string) {
if (form instanceof FormArray) {
console.log(suffix)
const formArray = form as FormArray;
const arr = [];
for (let i = 0; i < formArray.controls.length; i++) {
const control = formArray.at(i);
arr.push(
control instanceof FormGroup
? this.mergeForm(control, suffix + i+'.')
: control.valueChanges.pipe(
map((value) => ({ name: suffix + i, value: value }))
)
);
}
return merge(...arr);
}
return merge(
...Object.keys(form.controls).map((controlName: string) => {
const control = form.get(controlName);
return control instanceof FormGroup || control instanceof FormArray
? this.mergeForm(control, suffix + controlName + '.')
: control.valueChanges.pipe(
map((value) => ({ name: suffix + controlName, value: value }))
);
})
);
}
We can call in the way
this.mergeForm(this.orderForm, '')
.pipe(takeWhile((_) => this.alive))
.subscribe((res) => {
console.log(res);
});
You can see the stackblitz
NOTE: If you don't use FormArray you can simply the recursive function