Je souhaite créer un validateur personnalisé qui rendrait le bouton d'envoi disponible uniquement si le texte du formulaire est unique. J'ai une instance VulnarabilitiesClass, qui contient un tableau d'objets avec des champs id et name. Après avoir tapé du texte dans mon formulaire, j'obtiens cette erreur: Erreur: undefined n'est pas un objet (évaluation de 'this.systemVulnarabilities')
this.systemVulnarabilities = new VulnarabilitiesClass(); profileForm = this.fb.group({ name: ['', Validators.required,this.UniqueNameValidator], }); private UniqueNameValidator(control: FormControl): ValidationErrors{ let vulnarabilityName: string = control.value; console.log(vulnarabilityName); console.log(this.systemVulnarabilities.displayList.toString());//no output already let found: number = this.systemVulnarabilities.displayList.map(function(e) { return e.name; }).indexOf(vulnarabilityName); //mistake if(found === -1){ return {invalidPassword: 'this name already exists'}; } return null; }
<form [formGroup]="profileForm"> <label> Vulnarability Name: <input type="text" formControlName="name" required> </label> </form> <p> Form Status: {{ profileForm.status }} </p> <form [formGroup]="profileForm" (ngSubmit)="onSubmit()"> <button type="submit" [disabled]="!profileForm.valid">Submit</button>
3 Réponses :
Cette erreur se produit car la méthode UniqueNameValidator
est exécutée avec un contexte de composant différent de this
. La raison en est que dans le contexte javascript cela
dépend de la manière dont la fonction est exécutée et non de l'endroit où elle a été déclarée.
La solution simple consiste à utiliser Function.prototype.bind qui garantit un contexte correct ce
name: ['', [Validators.required, this.UniqueNameValidator.bind(this)]],
De plus, si votre validateur est synchrone, vous devez envelopper vos validateurs dans un tableau sinon Angular le traitera comme un validateur asynchrone:
this.UniqueNameValidator.bind(this)
l'autre manière "classique" est de définir la fonction comme
profileForm = this.fb.group({ name: ['', Validators.required,this.UniqueNameValidator()], });
et d'ajouter le validateur -voir le () à la fin de UniqueName Validator
private UniqueNameValidator(){ return (control: FormControl)=>{ .... } }
Je pense que vous pourriez utiliser une fermeture et rendre votre Validateur contextuel avec la variable systemVulnarabilities
, comme ceci:
UniqueNameValidator(systemVulnarabilities): ValidatorFn { return (control: FormControl)=>{ let vulnarabilityName: string = control.value; let found: number = systemVulnarabilities.displayList.map(function(e) { return e.name; }).indexOf(vulnarabilityName); //mistake if(found === -1){ return {invalidPassword: 'this name already exists'}; } return null; } }
profileForm = this.fb.group({ name: ['', Validators.required,this.UniqueNameValidator(systemVulnarabilities)], });
Pouvez-vous montrer votre code de classe de vulnérabilité?
peut-être afficher plus de code de classe de composant. Si "this.systemVulnarabilities n'est pas défini", il n'est certainement pas correctement instancié.