Błąd tslint / codelyzer / ng lint: „instrukcje (dla… w…) muszą być filtrowane za pomocą instrukcji if”


229

Komunikat o błędzie:

src / app / detail / edit / edit.component.ts [111, 5]: instrukcje (... w ...) muszą być filtrowane za pomocą instrukcji if

Fragment kodu (jest to działający kod. Jest również dostępny w sekcji sprawdzania poprawności formularza 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] + ' ';
        }
      }
    }

Masz pomysł, jak naprawić ten błąd włókna?


Może przyjąć odpowiedź?
Qwertiy

Odpowiedzi:


241

Aby wyjaśnić rzeczywisty problem, na który wskazuje tslint, cytat z dokumentacji JavaScript instrukcji for ... in :

Pętla będzie iterować wszystkie wyliczalne właściwości samego obiektu i tych, które dziedziczy po prototypie konstruktora (właściwości bliżej obiektu w łańcuchu prototypów zastępują właściwości prototypów).

Zasadniczo oznacza to, że otrzymasz właściwości, których możesz się nie spodziewać (z łańcucha prototypów obiektu).

Aby rozwiązać ten problem, musimy iterować tylko nad własnymi właściwościami obiektów. Możemy to zrobić na dwa różne sposoby (zgodnie z sugestiami @Maxxx i @Qwertiy).

Pierwsze rozwiązanie

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

W tym przypadku wykorzystujemy metodę Object.Keys () , która zwraca tablicę własnych wyliczalnych właściwości danego obiektu, w tej samej kolejności, jaką zapewnia pętla for ... in (różnica polega na tym, że pętla for in wylicza właściwości w łańcuch prototypów).

Drugie rozwiązanie

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

W tym rozwiązaniu iterujemy wszystkie właściwości obiektu, w tym właściwości jego łańcucha prototypowego, ale używamy metody Object.prototype.hasOwnProperty () , która zwraca wartość logiczną wskazującą, czy obiekt ma określoną właściwość jako własność (nie odziedziczoną), do filtrowania odziedziczone właściwości.


2
Chciałbym zauważyć, że Object.keysjest to ES5. Jedyną rzeczą z ES6 jest pętla for-of. Możemy iterować tablicę w zwykłej pętli od 0 do jej długości i będzie to ES5.
Qwertiy

4
jeszcze raz zauważ: jeśli w jakiś sposób this.formErrorsjest zerowy, for...inpo prostu nic nie rób, a to for ... of Object.keys()spowoduje błąd.
user3448806,

Idę za drugim rozwiązaniem, ale wciąż widzę komunikat o kłaczkach. Na razie wyłączone kłaczki.
raj240,

2
Dlaczego nie można polecić Object.keys(obj).forEach( key => {...}) ?
Ben Carp

268

Lepszym sposobem zastosowania odpowiedzi @ Helzgate jest zastąpienie słowa „za .. za”

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

6
To powinna być zaakceptowana odpowiedź, ponieważ nie tylko rozwiązuje problem, ale także zmniejsza ilość kodu płyty kotłowej w porównaniu do dodatkowych warunków warunkowych, takich jak if (this.formErrors.hasOwnProperty(field)).
Denialos,

1
Bądź ostrożny z odpowiedzią, może to złamać twoje kody. Przetestuj po „naprawieniu”.
ZZZ

3
To tak naprawdę nie usuwa dla mnie błędu tslint.
HammerN'Songs

7
@ HammerN'Songs sprawdzić, czy zmieniły się na z zamiast na w
Tom

mam ten sam problem. błąd nie jest usuwany po użyciu
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

użyj 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

Jeśli zachowanie for (... in ...) jest dopuszczalne / konieczne dla twoich celów, możesz powiedzieć tslint, aby zezwolił na to.

w tslint.json dodaj to do sekcji „reguły”.

"forin": false

W przeciwnym razie @Maxxx ma dobry pomysł

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.