Observables to the rescue! :)
Attach a form control to your search field, listen to the changes of it and filter the values. Return an observable to the template and use the async pipe there. Here is a sample for you, you just need to change the variable names to fit your needs:
The input with the form control:
<input [formControl]="searchCtrl" placeholder="Search"/>
Let's say your form looks like this:
this.myForm = this.fb.group({
formArr: this.fb.array([
this.fb.group({
formCtrl: ['one']
}),
//... more
])
});
// just a getter for your formarray
get formArr() {
return (this.myForm.get('formArr') as FormArray).controls;
}
Then listen in the component for the change and do the above mentioned filter. I like to put a slight debounce time before making the filter, if the user types fast.
Then the filtered formArr$ variable (which is an observable):
formArr$ = this.searchCtrl.valueChanges.pipe(
startWith(''),
debounceTime(300),
switchMap((val: string) => {
return of(this.formArr as AbstractControl[]).pipe(
map((formArr: AbstractControl[]) =>
formArr.filter((group: AbstractControl) => {
return group.get('formCtrl').value
.toLowerCase()
.includes(val.toLowerCase());
})
)
);
})
);
Then just use the async pipe in template:
<div *ngFor="let group of formArr$ | async">
<div formArrayName="formArr">
<div [formGroup]="group">
<input formControlName="formCtrl">
</div>
</div>
</div>
That's it! Here is a DEMO with the above code