I'm implementing a validator to check which lines have the same name.
I want to display an error message saying: "This line is duplicated" below the input box.
Now I'm customizing the FormArray validation so that it shows the error message line by line but don't know what to do next.
In app.component.html file:
<h4 class="bg-primary text-white p-2">
Check for duplicate names
</h4>
<div [formGroup]="formArray">
<div class="px-3 py-1"
*ngFor="let group of formArray.controls" [formGroup]="group">
Name <input formControlName="name"/>
Content <input formControlName="content" class="w-20" disabled/>
</div>
</div>
<hr>
<pre>
<b>Value :</b>
{{formArray.value | json}}
<b>Valid :</b> {{formArray.valid}}
<b>Errors :</b>
{{formArray.errors | json}}
</pre>
In app.component.ts file:
import { Component } from '@angular/core';
import { FormGroup, FormControl, FormArray, ValidatorFn } from '@angular/forms';
export function hasDuplicate(): ValidatorFn {
return (formArray: FormArray): { [key: string]: any } | null => {
const names = formArray.controls.map(x => x.get('name').value);
const check_hasDuplicate = names.some(
(name, index) => names.indexOf(name, index + 1) != -1
);
return check_hasDuplicate ? { error: 'Has Duplicate !!!' } : null;
};
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
formArray = new FormArray(
[
this.createGroup({ name: 'abc', content: '' }),
this.createGroup({ name: 'abc', content: '' }),
this.createGroup({ name: 'bcd', content: '' })
],
hasDuplicate()
);
createGroup(data: any) {
data = data || { name: null, content: null };
return new FormGroup({
name: new FormControl(data.name),
content: new FormControl(data.content)
});
}
}
I tried custom validator for each FormGroup inside FormArray but it has to scan and reset the whole FormGroups validator via keyup event. I don't feel very good.

