tslint / codelyzer / ng lint error: "las declaraciones for (... in ...) deben filtrarse con una declaración if"


229

Mensaje de error de pelusa:

src / app / detail / edit / edit.component.ts [111, 5]: para (... en ...) las declaraciones deben filtrarse con una declaración if

Fragmento de código (es un código de trabajo. También está disponible en la sección de validación del formulario 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] + ' ';
        }
      }
    }

¿Alguna idea de cómo solucionar este error de pelusa?


Tal vez aceptar una respuesta?
Qwertiy

Respuestas:


241

Para explicar el problema real que señala tslint, una cita de la documentación de JavaScript de for ... en la declaración :

El bucle iterará sobre todas las propiedades enumerables del objeto mismo y aquellas que el objeto herede del prototipo de su constructor (las propiedades más cercanas al objeto en la cadena del prototipo anulan las propiedades de los prototipos).

Entonces, básicamente, esto significa que obtendrá propiedades que podría no esperar obtener (de la cadena de prototipos del objeto).

Para resolver esto, necesitamos iterar solo sobre las propiedades propias de los objetos. Podemos hacer esto de dos maneras diferentes (como lo sugieren @Maxxx y @Qwertiy).

Primera solución

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

Aquí utilizamos el método Object.Keys () que devuelve una matriz de propiedades enumerables propias de un objeto dado, en el mismo orden que el proporcionado por un bucle for ... in (la diferencia es que un bucle for-in enumera propiedades en la cadena prototipo también).

Segunda solución

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

En esta solución, iteramos todas las propiedades del objeto, incluidas las de su cadena de prototipos, pero utilizamos el método Object.prototype.hasOwnProperty () , que devuelve un valor booleano que indica si el objeto tiene la propiedad especificada como propiedad propia (no heredada), para filtrar las propiedades heredadas


2
Me gustaría notar que Object.keyses ES5. Lo único de ES6 es for-of loop. Podemos iterar la matriz en el bucle habitual de 0 a su longitud y sería ES5.
Qwertiy

44
aviso una vez más: si de alguna manera this.formErrorses nulo, for...insimplemente no haga nada, mientras for ... of Object.keys()arrojaría un error.
user3448806

Estoy siguiendo la segunda solución pero aún veo el mensaje de pelusa. Pelusa desactivada por el momento.
raj240

2
¿Por qué no me recomiendan Object.keys(obj).forEach( key => {...}) ?
Ben Carp

268

Una forma más ordenada de aplicar la respuesta de @ Helzgate es posiblemente reemplazar su 'for ... in' con

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

66
Esta debería ser la respuesta aceptada, ya que no solo resuelve el problema, sino que también reduce la cantidad de código repetitivo en comparación con condicionales adicionales como if (this.formErrors.hasOwnProperty(field)).
Denialos

1
Tenga cuidado con la respuesta, podría romper sus códigos. Pruebe después de "arreglarlo".
ZZZ

3
Esto en realidad no elimina el error tslint para mí.
HammerN'Songs

77
@ HammerN'Songs comprobar que los ha cambiado a para de vez de para en
Tom

el mismo problema aqui. error no se elimina después de usar esto
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

use 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

Si el comportamiento de for (... in ...) es aceptable / necesario para sus propósitos, puede decirle a tslint que lo permita.

en tslint.json, agregue esto a la sección "reglas".

"forin": false

De lo contrario, @Maxxx tiene la idea correcta con

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.