tslint / codelyzer / ng fusselfehler: "for (… in…) Anweisungen müssen mit einer if-Anweisung gefiltert werden"


229

Flusenfehlermeldung:

src / app / detail / edit / edit.component.ts [111, 5]: for (... in ...) Anweisungen müssen mit einer if-Anweisung gefiltert werden

Code-Snippet (Es handelt sich um einen Arbeitscode . Er ist auch im Abschnitt zur Überprüfung des Formulars angle.io verfügbar. ):

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] + ' ';
        }
      }
    }

Irgendeine Idee, wie man diesen Flusenfehler behebt?


Vielleicht eine Antwort annehmen?
Qwertiy

Antworten:


241

Um das eigentliche Problem zu erklären, auf das tslint hinweist, ein Zitat aus der JavaScript-Dokumentation der for ... in-Anweisung :

Die Schleife durchläuft alle aufzählbaren Eigenschaften des Objekts selbst und die Eigenschaften, die das Objekt vom Prototyp seines Konstruktors erbt (Eigenschaften, die näher am Objekt in der Prototypkette liegen, überschreiben die Eigenschaften der Prototypen).

Im Grunde bedeutet dies, dass Sie Eigenschaften erhalten, die Sie möglicherweise nicht erwarten (aus der Prototypenkette des Objekts).

Um dies zu lösen, müssen wir nur über die eigenen Eigenschaften des Objekts iterieren. Wir können dies auf zwei verschiedene Arten tun (wie von @Maxxx und @Qwertiy vorgeschlagen).

Erste Lösung

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

Hier verwenden wir die Object.Keys () -Methode, die ein Array der eigenen aufzählbaren Eigenschaften eines bestimmten Objekts in derselben Reihenfolge zurückgibt, wie sie von einer for ... in-Schleife bereitgestellt wird (der Unterschied besteht darin, dass eine for-in-Schleife Eigenschaften in auflistet auch die Prototypenkette).

Zweite Lösung

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

In dieser Lösung iterieren wir alle Eigenschaften des Objekts, einschließlich derjenigen in seiner Prototypkette, verwenden jedoch die Methode Object.prototype.hasOwnProperty () , die einen Booleschen Wert zurückgibt, der angibt, ob das Objekt die angegebene Eigenschaft als eigene (nicht geerbte) Eigenschaft hat, um zu filtern die geerbten Eigenschaften aus.


2
Ich würde gerne bemerken, dass dies Object.keysES5 ist. Das einzige, was es von ES6 gibt, ist eine For-of-Schleife. Wir können das Array in der üblichen Schleife von 0 bis zu seiner Länge iterieren und es wäre ES5.
Qwertiy

4
Noch einmal beachten: Wenn irgendwie this.formErrorsnull ist, for...intun Sie einfach nichts, während for ... of Object.keys()Fehler werfen würde.
user3448806

Ich folge der zweiten Lösung, aber ich sehe immer noch die Flusenmeldung. Flusen vorerst deaktiviert.
Raj240

2
Warum empfehlen Sie nicht Object.keys(obj).forEach( key => {...}) ?
Ben Carp

268

Eine bessere Möglichkeit, die Antwort von @ Helzgate anzuwenden, besteht möglicherweise darin, Ihr 'for .. in' durch zu ersetzen

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

6
Dies sollte die akzeptierte Antwort sein, da dies nicht nur das Problem löst, sondern auch die Menge des Boilerplate-Codes im Vergleich zu zusätzlichen Bedingungen wie z if (this.formErrors.hasOwnProperty(field)).
Denialos

1
Seien Sie vorsichtig mit der Antwort, sie könnte Ihre Codes beschädigen. Testen Sie, nachdem Sie es "repariert" haben.
ZZZ

3
Dies entfernt den tslint-Fehler für mich nicht wirklich.
HammerN'Songs

7
@ HammerN'Songs überprüfen, dass Sie für für statt für in
Tom

selbes Problem hier. Fehler wird nicht entfernt, nachdem dies verwendet wurde
llamerr

71
for (const field in this.formErrors) {
  if (this.formErrors.hasOwnProperty(field)) {
for (const key in control.errors) {
  if (control.errors.hasOwnProperty(key)) {

13

benutze 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] + ' ';
    });
  }
});

2

Wenn das Verhalten von for (... in ...) für Ihre Zwecke akzeptabel / notwendig ist, können Sie tslint anweisen, es zuzulassen.

Fügen Sie dies in tslint.json dem Abschnitt "Regeln" hinzu.

"forin": false

Ansonsten hat @Maxxx die richtige Idee mit

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.