Erro tslint / codelyzer / ng lint: “as instruções for (… in…) devem ser filtradas com uma instrução if”

229

Mensagem de erro do fiapo:

src / app / detail / edit / edit.component.ts [111, 5]: as instruções for (... in ...) devem ser filtradas com uma instrução if

Fragmento de código (é um código funcional. Também está disponível na seção de validação de formulário 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] + ' ';
        }
      }
    }

Alguma idéia de como corrigir esse erro de cotão?

choopage - Jek Bao
fonte
Talvez aceite uma resposta?
Qwertiy em 21/04

Respostas:

241

Para explicar o problema real que o tslint está apontando, uma citação da documentação JavaScript do for ... na declaração :

O loop iterará sobre todas as propriedades enumeráveis ​​do próprio objeto e aquelas que o objeto herda do protótipo de seu construtor (as propriedades mais próximas ao objeto na cadeia de protótipos substituem as propriedades dos protótipos).

Então, basicamente, isso significa que você obterá propriedades que você não esperaria obter (da cadeia de protótipos do objeto).

Para resolver isso, precisamos iterar apenas sobre as propriedades do próprio objeto. Podemos fazer isso de duas maneiras diferentes (como sugerido por @Maxxx e @Qwertiy).

Primeira solução

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

Aqui, utilizamos o método Object.Keys () que retorna uma matriz das propriedades enumeráveis ​​de um determinado objeto, na mesma ordem que a fornecida por um loop for ... in (a diferença é que um loop for enumera propriedades em a cadeia de protótipos).

Segunda solução

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

Nesta solução, iteramos todas as propriedades do objeto, incluindo as da cadeia de protótipos, mas usamos o método Object.prototype.hasOwnProperty () , que retorna um booleano indicando se o objeto tem a propriedade especificada como propriedade própria (não herdada), para filtrar as propriedades herdadas.

akrabi
fonte
2
Eu gostaria de notar que Object.keysé o ES5. A única coisa do ES6 é o loop for-of. Podemos iterar a matriz no loop usual de 0 a seu comprimento e seria ES5.
Qwertiy
4
mais uma vez aviso: se de alguma forma this.formErrorsé nulo, for...inapenas não faça nada, enquanto for ... of Object.keys()lançaria erro.
user3448806
Estou seguindo a segunda solução, mas ainda vejo a mensagem do fiapo. Fiapos desativados por enquanto.
raj240 02/02/19
2
Por que você não recomenda Object.keys(obj).forEach( key => {...}) ?
Ben Carp
268

Uma maneira mais clara de aplicar a resposta do @ Helzgate é possivelmente substituir o seu 'for .. in' por

for (const field of Object.keys(this.formErrors)) {
Maxxx
fonte
6
Essa deve ser a resposta aceita, pois além de resolver o problema, também reduz a quantidade de código padrão em comparação com condicionais adicionais, como if (this.formErrors.hasOwnProperty(field)).
Denialos
1
Tenha cuidado com a resposta, pois isso pode quebrar seus códigos. Teste depois de "corrigi-lo".
ZZZ
3
Na verdade, isso não remove o erro tslint para mim.
HammerN'Songs
7
@ HammerN'Songs verifique se mudou para a de , em vez de para em
Tom
mesmo problema aqui. erro não é removido após o uso
llamerr 27/11
71
for (const field in this.formErrors) {
  if (this.formErrors.hasOwnProperty(field)) {
for (const key in control.errors) {
  if (control.errors.hasOwnProperty(key)) {
Qwertiy
fonte
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] + ' ';
    });
  }
});
Helzgate
fonte
2

Se o comportamento de for (... em ...) for aceitável / necessário para seus propósitos, você pode dizer ao tslint para permitir isso.

no tslint.json, adicione isso à seção "rules".

"forin": false

Caso contrário, o @Maxxx tem a ideia certa com

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

Eu acho que esta mensagem não é sobre como evitar o uso switch. Em vez disso, deseja que você verifique hasOwnProperty. O plano de fundo pode ser lido aqui: https://stackoverflow.com/a/16735184/1374488

lukas_o
fonte