erreur tslint / codelyzer / ng lint: «les instructions for (… in…) doivent être filtrées avec une instruction if»

229

Message d'erreur sur les peluches:

src / app / detail / edit / edit.component.ts [111, 5]: les instructions for (... in ...) doivent être filtrées avec une instruction if

Extrait de code (Il s'agit d'un code de travail. Il est également disponible dans la section de validation du formulaire angular.io ):

for (const field in this.formErrors) {
      // clear previous error message (if any)
      this.formErrors[field] = '';
      const control = form.get(field);

      if (control && control.dirty && !control.valid) {
        const messages = this.validationMessages[field];
        for (const key in control.errors) {
          this.formErrors[field] += messages[key] + ' ';
        }
      }
    }

Une idée comment corriger cette erreur de peluche?

choopage - Jek Bao
la source
Peut-être accepter une réponse?
Qwertiy

Réponses:

241

Pour expliquer le problème réel signalé par tslint, une citation de la documentation JavaScript du for ... in :

La boucle parcourra toutes les propriétés énumérables de l'objet lui-même et celles dont l'objet hérite du prototype de son constructeur (les propriétés plus proches de l'objet dans la chaîne de prototype remplacent les propriétés des prototypes).

Donc, fondamentalement, cela signifie que vous obtiendrez des propriétés que vous ne vous attendez pas à obtenir (à partir de la chaîne de prototypes de l'objet).

Pour résoudre ce problème, nous devons itérer uniquement sur les propriétés propres des objets. Nous pouvons le faire de deux manières différentes (comme suggéré par @Maxxx et @Qwertiy).

Première solution

for (const field of Object.keys(this.formErrors)) {
    ...
}

Ici, nous utilisons Object.Keys () méthode qui renvoie un tableau des propriétés énumérables d'un objet donné, dans le même ordre que celui fourni par une boucle for ... in (la différence étant qu'une boucle for-in énumère les propriétés dans la chaîne prototype également).

Deuxième solution

for (var field in this.formErrors) {
    if (this.formErrors.hasOwnProperty(field)) {
        ...
    }
}

Dans cette solution, nous itérons toutes les propriétés de l'objet, y compris celles de sa chaîne de prototypes, mais utilisons la méthode Object.prototype.hasOwnProperty () , qui renvoie un booléen indiquant si l'objet possède la propriété spécifiée comme propriété propre (non héritée), pour filtrer les propriétés héritées sur.

akrabi
la source
2
Je voudrais remarquer que Object.keysc'est ES5. La seule chose d'ES6 est la boucle for-of. Nous pouvons parcourir le tableau en boucle habituelle de 0 à sa longueur et ce serait ES5.
Qwertiy
4
remarquez encore une fois: si en quelque sorte this.formErrorsest nul, for...inne faites rien, tandis que for ... of Object.keys()lancerait une erreur.
user3448806
je suis la deuxième solution mais je vois toujours le message de peluches. Peluche désactivée pour le moment.
raj240
2
Pourquoi ne recommandez-vous pas Object.keys(obj).forEach( key => {...}) ?
Ben Carp
268

Une meilleure façon d'appliquer la réponse de @ Helzgate est peut-être de remplacer votre «for .. in» par

for (const field of Object.keys(this.formErrors)) {
Maxxx
la source
6
Cela devrait être la réponse acceptée car non seulement cela résout le problème, mais cela réduit également la quantité de code passe-partout par rapport à des conditions supplémentaires telles que if (this.formErrors.hasOwnProperty(field)).
Denialos
1
Soyez prudent avec la réponse, cela pourrait casser vos codes. Testez après l'avoir "réparé".
ZZZ
3
Cela ne supprime pas réellement l'erreur tslint pour moi.
HammerN'Songs
7
@ HammerN'Songs vérifier que vous avez changé à pour de lieu de pour en
Tom
Même problème ici. erreur n'est pas supprimée après avoir utilisé ceci
llamerr
71
for (const field in this.formErrors) {
  if (this.formErrors.hasOwnProperty(field)) {
for (const key in control.errors) {
  if (control.errors.hasOwnProperty(key)) {
Qwertiy
la source
13

utilisez Object.keys:

Object.keys(this.formErrors).map(key => {
  this.formErrors[key] = '';
  const control = form.get(key);

  if(control && control.dirty && !control.valid) {
    const messages = this.validationMessages[key];
    Object.keys(control.errors).map(key2 => {
      this.formErrors[key] += messages[key2] + ' ';
    });
  }
});
Helzgate
la source
2

Si le comportement de for (... in ...) est acceptable / nécessaire pour vos besoins, vous pouvez dire à tslint de l'autoriser.

dans tslint.json, ajoutez ceci à la section "règles".

"forin": false

Sinon, @Maxxx a la bonne idée avec

for (const field of Object.keys(this.formErrors)) {
pseudo
la source
0

Je pense que ce message ne vise pas à éviter d'utiliser switch. Au lieu de cela, il veut que vous vérifiiez hasOwnProperty. Le fond peut être lu ici: https://stackoverflow.com/a/16735184/1374488

lukas_o
la source