27
respostas

Can't bind to 'ngforOf' since it isn't a known property of 'tr'

Bom dia Devs, criei um component para listar e editar uma certa Grid, porém estou com o erro acima, de primeira vista era porque o CommonModule e o BrowserModule não estavam importados, porém já verifiquei estão todos importados, o que estou fazendo de errado?

<tbody>
                            <tr *ngfor="let params of parametro">
                                <td>{{params.parametroNome}}</td>
                                <td>
                                    <input type="text" class="form-control" value="{{params.parametroValor}}"> 
                                </td>
                            </tr>
                        </tbody>

Meu Componente

import { GenericService } from 'app/repositories/common/generic.service';
import { Observable } from 'rxjs/Observable';
import { GenericServiceFactory } from 'app/repositories/common/generic-service-factory.service';
import { Component, OnInit, Input, Output, EventEmitter, ElementRef } from '@angular/core';
import { Router } from '@angular/router';
import { Parametro } from 'app/model/parametro';
import { IParametro } from 'app/model/parametro.model';
import { IError } from 'app/model/error.model';
import { ToastsManager } from 'ng2-toastr';


@Component({
  templateUrl: '../../../views/parametro/parametro.component.html'
})

export class ParametroComponent implements OnInit {

  parametro: Observable<IParametro[]>
  modulo: string

  salvando: boolean

  service: GenericService<IParametro>

  constructor(private serviceFactory: GenericServiceFactory, 
              private toastr: ToastsManager,
              private router: Router) {
    this.service = serviceFactory.createHttpServiceFor<IParametro>('parametro');
    this.modulo = localStorage.getItem('currentModule');
  }

  ngOnInit(): void {
      this.getAllParametros();
  }

  getAllParametros(){
    this.parametro = this.service.getAll();
  }

  updateParametro(param: IParametro) {
    this.service.putWithoutId(param)
    .catch((err: IError) => {
        this.salvando = false;
        this.toastr.error(err.message, 'Atualização de parâmetro');
        return Observable.throw(err);
    })
    .subscribe((result) => {
        this.toastr.success('Parâmetro atualizado com sucesso', 'Atualização de parâmetro');
    });

  }

}
27 respostas

Olá, Rafael.

No seu TS, adiciona um console.log conforme o código abaixo pra ver se estamos preenchendo um conteúdo pro atributo this.parametro do obejto:

getAllParametros(){
    console.log('Valor', this.service.getAll())
    this.parametro = this.service.getAll();
}

Marco Bruno, o erro ainda continua e o console.log não retornou nada no console do browser, o que mais pode ser?

ERROR Error: Uncaught (in promise): Error: Template parse errors:
Can't bind to 'ngforOf' since it isn't a known property of 'tr'. ("
                        </thead>
                        <tbody>
                            <tr [ERROR ->]*ngfor="let params of parametro">
                                <td>{{params.parametroNome}}</td>
"): ng:///ConfiguracaoModule/ParametroComponent.html@52:32
Property binding ngforOf not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("
                        </thead>
                        <tbody>
                            [ERROR ->]<tr *ngfor="let params of parametro">
                                <td>{{params.parametroNome}}</"): ng:///ConfiguracaoModule/ParametroComponent.html@52:28
Error: Template parse errors:
Can't bind to 'ngforOf' since it isn't a known property of 'tr'. ("
                        </thead>
                        <tbody>
                            <tr [ERROR ->]*ngfor="let params of parametro">
                                <td>{{params.parametroNome}}</td>
"): ng:///ConfiguracaoModule/ParametroComponent.html@52:32
Property binding ngforOf not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("
                        </thead>
                        <tbody>
                            [ERROR ->]<tr *ngfor="let params of parametro">
                                <td>{{params.parametroNome}}</"): ng:///ConfiguracaoModule/ParametroComponent.html@52:28

Olá Marco, consegui resolver o erro e o Console.log retornou o objeto, mas ainda não resolvi o que queria.

Não entendi, Rafael. O console.log está retornando o valor, mas você está recebendo a mensagem de erro?

sim, mas agora o erro é outro:

Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

Alguém pode me ajudar!!??

Rafael. Desculpa pela demora estava em aula na Caelum.

Parece que você não está passando um Array de objeto ou um Interable para o atributo this.paramentro. Verifica qual é o retorno que está vindo do seu service.

Marco ele retorna um Observable de uma interface, no caso uma interface IParametro que estou passando na ts. Como eu poderia fazer?

@Injectable()
export class GenericService<T> {
    constructor(protected http: HttpClient,
                protected resource: string) { }

    getAll(): Observable<T> {
        const url = `v1/${this.resource}?page=1&limit=99999&somenteAtivos=false&search=&sort=`;

        return this.http.get(url)
            .map(res => <T[]>res.json().data)
            .catch((error: any) => Observable.throw(this.handleError(error)));
    }

Essa eu vou demorar um pouco pra responder, preciso comer antes de voltar pra aula. Desculpa :-)

Tabom Marco Bom Apepetit, quando tiver um tempo quebra esse galho kkkk

Rafael, como já estou voltando pra aula, não sei se vai funcionar, mas tenta trocar o retorno do método getAll de Observable pra Array ou Iterable.

É realmente ainda não funcionou :[

Vou pedir ajuda pra mais gente aqui, que agora estou na aula e ficarei sem tempo pra te ajudar :-(

Boa tarde Rafael,

a diretiva *ngFor tem o F maiúsculo. Talvez seja isto. Veja também este exemplo: https://blog.angular-university.io/angular-2-ngfor/

Espero que ajude, abraços e bons estudos.

Boa tarde Vanessa, o *ngFor esta com o F maiúsculo, mas creio que seja algo haver com o retorno do meu método pois o erro acusa que não é possível encontrar um objeto de suporte diferente '[objeto Objeto]' do tipo 'objeto'. NgFor só suporta ligação a Iterables, como Arrays.

<tr *ngFor="let param of parametro">
                                <td>{{param.parametroNome}}</td>
                                <td>
                                    <input type="text" class="form-control" value="{{param.parametroValor}}"> 
                                </td>
                            </tr>

Rafael, no seu template, retire o *ngFor para parar este erro no console por enquanto, e com o Angular Expression use o pipe json, para vermos o que retorna da sua propriedade parametro.

exemplo:

{{parametro | json}}

e cole aqui o resultado.

deu um erro :

TypeError: Converting circular structure to JSON
<tr>
             <td>{{parametro | json}}</td>
            <td>
                    <input type="text" class="form-control"> 
          </td>
</tr>

Rafael, você pode explicar o que era/é pra acontecer neste trecho do código do seu serviço?

.map(res => <T[]>res.json().data)

A dúvida é :

Como faço o loop através de um Array que está dentro de um observablel?

Então, no caso ele apenas mapeia uma Interface como Array <T[]>que será definida , e devolve como resposta um json.

.map(res => <T[]>res.json().data)

Olha eu nunca fiz isso, mas pelo que pesquisei aqui, pode ser algo como:

<tr *ngFor="let param of parametro | async">

referência: https://stackoverflow.com/questions/41659736/how-to-iterate-over-an-observable-stream-of-arrays-in-angular-2-templates

Bom dia, Realmente com isso o erro sumiu, mas ainda não consegui listar os dados na minha tabela, ela se encontra em branco.

Rafael, fiquei pensando ontem no seu código, e acho que talvez seja bom vc usar o subscribe no getAllParameters, conforme o professor mostra no curso. E talvez não precisa usar o map...

Algo como:

getAllParametros(){
    this.parametro = this.service
                         .getAll()
                         .subscribe(
                              resposta => <T[]>resposta.json().data
                            , erro => console.log(erro)
                         )

}

no serviço

getAll(): Observable<Response>  {
        const url = `v1/${this.resource}?page=1&limit=99999&somenteAtivos=false&search=&sort=`

        return this.http.get(url)
    }

Veja se ajuda...

Quase lá, estou apenas com um erro nesta linha const results = res.json(); Property 'json' does not exist on type 'IParametro[]'. Que é o Retorno do getAll(), ja coloquei o Observable mas da erro.

export class ParametroComponent implements OnInit { 
  parametro: any[];
  modulo: string

  salvando: boolean

  service: GenericService<IParametro>

  constructor(private serviceFactory: GenericServiceFactory, 
              private toastr: ToastsManager,
              private router: Router) {
    this.service = serviceFactory.createHttpServiceFor<IParametro>('parametro');
    this.modulo = localStorage.getItem('currentModule');
  }

  ngOnInit(): void {
      this.getAllParametros();
  }

  getAllParametros(){
      console.log('Valor', this.service.getAll());
      this.service.getAll().subscribe(res => {
      const results = res.json();
      this.parametro = results.data;
    });
  }

  updateParametro(param: IParametro) {
    this.service.putWithoutId(param)
    .catch((err: IError) => {
        this.salvando = false;
        this.toastr.error(err.message, 'Atualização de parâmetro');
        return Observable.throw(err);
    })
    .subscribe((result) => {
        this.toastr.success('Parâmetro atualizado com sucesso', 'Atualização de parâmetro');
    });

  }

}

é porque o .json() é um método para um determinado tipo, você só pode usar ele em tipos Body da response. Porém eu não to sacando pq vc precisa colocar no seu response do serviço assim <T[]>res ... por isso pedi pra você me explicar o que estava acontecendo nesta linha... Veja a documentação do método json() https://developer.mozilla.org/en-US/docs/Web/API/Body/json