I have an array of FormGroups which all holds one FormControl called checked which is represented as a checkbox input in the template.
This array formGroups$ is computed from another Observable called items$.
// component.ts
constructor(private fb: FormBuilder) {}
items$ = of([{ whatever: 'not used' }, { something: 'doesnt matter' }]);
// doesn't work!
formGroups$: Observable<FormGroup<{ checked: FormControl<boolean> }>[]> =
this.items$.pipe(
map((items) => {
const array: FormGroup[] = [];
for (const item of items) {
const formGroup = this.fb.group({});
formGroup.addControl('checked', new FormControl(false));
array.push(formGroup);
}
return array;
})
);
allChecked$: Observable<boolean> = this.formGroups$.pipe(
switchMap((formGroups) => {
const valueChangesArray: Observable<boolean>[] = [];
formGroups.forEach((formGroup) => {
valueChangesArray.push(
formGroup
.get('checked')
.valueChanges.pipe(startWith(formGroup.get('checked').value))
);
});
return combineLatest(valueChangesArray);
}),
map((checkedValues) => {
console.log(checkedValues);
for (const isChecked of checkedValues) {
if (!isChecked) {
return false;
}
}
return true;
})
);
<!-- component.html -->
<ng-container *ngFor="let formGroup of formGroups$ | async; index as i">
<label>
<input type="checkbox" [formControl]="formGroup.controls.checked" />
{{ i }}
</label>
</ng-container>
<p>allChecked: {{ allChecked$ | async }}</p>
Example see also in Stackblitz: https://stackblitz.com/edit/angular-ivy-xfpywy?file=src%2Fapp%2Fapp.component.ts
Now when I try to compute if all those checkboxes are checked with allChecked$, which combines all Observables from each FormGroups formControl.valueChanges, the map in there only gets triggered once and not as expected every time the value of a Checkbox changes:
If I change formGroup$ to a simpler static solution, the value allChecked$ is computed correctly every time:
// works!
formGroups$: Observable<FormGroup<{ checked: FormControl<boolean> }>[]> = of([
new FormGroup({
checked: new FormControl(false),
}),
new FormGroup({
checked: new FormControl(true),
}),
]);
You can easily reproduce it in this StackBlitz: https://stackblitz.com/edit/angular-ivy-xfpywy?file=src%2Fapp%2Fapp.component.ts
How do I compute this boolean allChecked$ with an array of dynamically created FormGroups?
