kesalahan tslint / codelyzer / ng lint: "untuk (... dalam ...) pernyataan harus disaring dengan pernyataan if"

229

Pesan kesalahan serat:

src / app / detail / edit / edit.component.ts [111, 5]: untuk (... dalam ...) pernyataan harus disaring dengan pernyataan if

Cuplikan kode (Ini adalah kode yang berfungsi. Ini juga tersedia di bagian validasi formulir 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] + ' ';
        }
      }
    }

Adakah cara untuk memperbaiki kesalahan serat ini?

choopage - Jek Bao
sumber
Mungkin menerima jawaban?
Qwertiy

Jawaban:

241

Untuk menjelaskan masalah aktual yang ditunjukkan tslint, kutipan dari dokumentasi JavaScript untuk ... dalam pernyataan :

Lingkaran akan beralih pada semua properti enumerable dari objek itu sendiri dan yang diwarisi objek dari prototipe konstruktornya (properti lebih dekat ke objek dalam rantai prototipe menimpa properti prototipe).

Jadi, pada dasarnya ini berarti Anda akan mendapatkan properti yang mungkin tidak Anda harapkan (dari rantai prototipe objek).

Untuk mengatasi ini, kita perlu beralih hanya pada properti yang dimiliki objek. Kita dapat melakukan ini dengan dua cara berbeda (seperti yang disarankan oleh @Maxxx dan @Qwertiy).

Solusi pertama

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

Di sini kita menggunakan metode Object.Keys () yang mengembalikan array dari properti enumerable milik objek tertentu, dalam urutan yang sama seperti yang disediakan oleh for ... in loop (perbedaannya adalah for-in loop menyebutkan properti di rantai prototipe juga).

Solusi kedua

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

Dalam solusi ini kami mengulangi semua properti objek termasuk yang ada di rantai prototipe tetapi menggunakan metode Object.prototype.hasOwnProperty () , yang mengembalikan boolean yang menunjukkan apakah objek memiliki properti yang ditentukan sebagai properti yang dimiliki (tidak diwariskan), untuk memfilter properti warisan keluar.

akrabi
sumber
2
Saya ingin memperhatikan bahwa Object.keysES5. Satu-satunya hal dari ES6 ada for-of loop. Kita dapat mengulangi array dalam loop biasa dari 0 hingga panjangnya dan itu akan menjadi ES5.
Qwertiy
4
pemberitahuan sekali lagi: jika entah bagaimana this.formErrorsadalah nol, for...inlakukan saja, sementara for ... of Object.keys()akan membuang kesalahan.
user3448806
saya mengikuti solusi kedua tetapi saya masih melihat pesan serat. Serat dinonaktifkan untuk sementara waktu.
raj240
2
Kenapa tidak Anda rekomendasikan Object.keys(obj).forEach( key => {...}) ?
Ben Carp
268

Cara yang lebih rapi dalam menerapkan balasan @ Helzgate adalah dengan mengganti 'untuk .. masuk' dengan

for (const field of Object.keys(this.formErrors)) {
Maks
sumber
6
Ini harus menjadi jawaban yang diterima karena tidak hanya memecahkan masalah, tetapi juga mengurangi jumlah kode boilerplate dibandingkan dengan kondisional tambahan seperti if (this.formErrors.hasOwnProperty(field)).
Denialos
1
Hati-hati dengan jawabannya, itu bisa merusak kode Anda. Tes setelah Anda "memperbaikinya".
ZZZ
3
Ini sebenarnya tidak menghapus kesalahan tslint untuk saya.
HammerN'Songs
7
@ HammerN'Songs memeriksa bahwa Anda berubah ke untuk dari bukan untuk di
Tom
Masalah yang sama disini. kesalahan tidak dihapus setelah menggunakan ini
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
sumber
13

gunakan 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
sumber
2

Jika perilaku for (... in ...) dapat diterima / diperlukan untuk tujuan Anda, Anda dapat memberi tahu tslint untuk mengizinkannya.

di tslint.json, tambahkan ini ke bagian "aturan".

"forin": false

Jika tidak, @Maxxx memiliki ide yang tepat

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

Saya pikir pesan ini bukan tentang menghindari penggunaan switch. Sebaliknya ia ingin Anda memeriksanya hasOwnProperty. Latar belakang dapat dibaca di sini: https://stackoverflow.com/a/16735184/1374488

lukas_o
sumber