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?

choopage - Jek Bao
źródło
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.

akrabi
źródło
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)) {
Maxxx
źródło
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)) {
Qwertiy
źródło
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] + ' ';
    });
  }
});
Helzgate
źródło
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)) {
Nacięcie
źródło
0

Myślę, że w tym komunikacie nie chodzi o unikanie używania switch. Zamiast tego chce, abyś sprawdził hasOwnProperty. Tło można przeczytać tutaj: https://stackoverflow.com/a/16735184/1374488

lukas_o
źródło