4
respostas

ngFor em um Objeto complexo

Boa tarde Flávio. Não estou conseguindo listar no HTML o resultado retornado de uma API com as seguinte JSON:

{
    "cliente": {
        "id": 552913400,
        "cpf": "000000000",
        "nome": "JOSÉ DA SILVA",
        "contratos": [{
            "id": "00000000017",
            "dataEmissao": 1496372400000,
            "menorParcela": 10,
            "quantidadeParcelas": 48,
            "agente": {
                "id": 000
            },
            "agenteResponsavel": {
                "id": 000
            },
            "carteira": {},
            "valorTotal": 0.00,
            "valorDivida": 0.00,
            "valorParcela": 0.00,
            "diasAtraso": 60,
            "descricao": "LEVE",
            "menorDataVenvcimento": 1523070000000,
            "dataUltimoPagamento": 1522724400000,
            "quantidadeParcelaAtrasada": 0,
            "taxaContrato": 0.00,
            "acordos": [{
                "status": {
                    "descricao": "Acordo aguardando pagamento"
                },
                "valor": 0,
                "valorEntrada": 0.00,
                "valorDivida": 0.00,
                "quantidadeParcelasAcordo": 0,
                "composicao": [],
                "parcelas": [],
                "despesas": [],
                "log": [],
                "valorTotalAcordo": 0.00
            }]
        }, {
            "id": "000000015",
            "dataEmissao": 1444705200000,
            "menorParcela": 1,
            "quantidadeParcelas": 3,
            "agente": {
                "id": 00
            },
            "agenteResponsavel": {
                "id": 00
            },
            "carteira": {},
            "valorTotal": 0,
            "valorDivida": 0,
            "valorParcela": 0.00,
            "diasAtraso": 0,
            "descricao": "VEÍCULO LEVE",
            "menorDataVenvcimento": 1447552800000,
            "dataUltimoPagamento": 1496372400000,
            "quantidadeParcelaAtrasada": 0,
            "taxaContrato": 0,
            "acordos": [{
                "status": {},
                "valor": 0,
                "valorEntrada": 0,
                "valorDivida": 0,
                "composicao": [],
                "parcelas": [],
                "despesas": [],
                "log": [],
                "valorTotalAcordo": 0
            }]
        }],
        "quantidadeContratos": 1
    },
    "status": "SUCCESS"
}

Preciso listar o resultado no ngFor dos contratos{}

Meu resultado vem em um objeto abaixo:

    this.listaContratoService
      .getListaContratoCliente()
      .subscribe(
        res => {
              this.listContrato = res;
              console.log(this.listContrato);
            },
        err => { 
                   console.log(err.status);
                   if (err.status != 404){
                     alert("Erro: "+ err.status);
                   } else {
                    this.localizadoContrato = "Não foi localizado nenhum contrato para este cliente.";
                   }

               }  
      ) ;

Como tenho que colocar no meu ngFor para funcionar no HTML, estou colocando como abaixo e ele encontra, mas não lista.

  <div class="offer offer-default">
    <div class="offer-content">
        <div *ngIf="undefined !== listContrato">
      <div class="table-responsive">
        <table class="table  table-hover">
        <thead>
            <tr>
            <th>Nº Contrato</th>
            <th>Emissão</th>
            <th>Produto</th>
            <th>Menor Parcela</th>
            </tr>
        </thead>
        <tbody>
          <tr *ngFor="let registro of listContrato['cliente.contrato']">
            <td> {{ registro.cliente.contratos.id }} </td>

Me ajuda, por favor. Obrigado.

4 respostas

Oi, André.

Você está acessando contrato ao invés de contratos como mostra no seu JSON. E também a variável que você acessa dentro do seu ngFor deve ser somente registro.id uma vez que as propriedades cliente.contratos de listContrato já foram acessadas.

<tr *ngFor="let registro of listContrato['cliente.contratos']">
            <td> {{ registro.id }} </td>

Caso você não tenha interesse no restante dos dados você pode acessar diretamente no seu componente também:

        res => this.listContrato = res.cliente.contratos;
<tr *ngFor="let registro of listContrato">
            <td> {{ registro.id }} </td>

Abs.

Flávio, quando coloco no component res.cliente.contratos o angular reclama informando "[ts] A propriedade 'cliente' não existe no tipo 'ContratoCobranca[]'."

porém minha interface está desta forma:

export interface ContratoCobranca{
    cliente: {
        id: number,
        cpf: string,
        nome: string,
        contratos: [{
            id: string,
            dataEmissao: Date,
            menorParcela: number,
            quantidadeParcelas: number,
            agente: {
                id: number
            },
            agenteResponsavel: {
                id: number
            },
            carteira: {
                id: number,
                nome: string,
                contratoOriginal: string
            },
            valorTotal: number,
            valorDivida: number,
            valorParcela: number,
            diasAtraso: number,
            descricao: string,
            menorDataVenvcimento: Date,
            dataUltimoPagamento: Date,
            quantidadeParcelaAtrasada: number,
            taxaContrato: number,
            acordos: [{
                status: {
                    descricao: string
                },
                valor: number,
                valorEntrada: number,
                valorDivida: number,
                quantidadeParcelasAcordo: number,
                valorTotalAcordo: number
            }]
        }],
        quantidadeContratos: number
    },
    status: string
}

O que estou fazendo de errado?

Ajustei como você me orientou e estava errado mesmo, porém continua não listando os contratos, o que me parece que não está reconhecendo o "cliente".

Obrigado.

E declarado também o array desta forma:

listContrato: ContratoCobranca[] = [];

Fico no aguardo, obrigado.

Oi, André. Não sou o Flávio, me chamo Darlan rs.

Bom, como o retorno do seu back-end é um array de ContratoCobranca a coisa muda um pouco de figura. O acesso as propriedades vai ficar por parte da variável registro que vai conter seu objeto, note que seu listContrato é um array de clientes, com vários objetos. Então de fato, listContratos.cliente.contratos não existe. Outro ponto, é que seu array de ContratoCobranca tem outro array de contratos. No seu template ficaria algo como:

<tr *ngFor="let registro of listContrato">
    <tr *ngFor="let reg of registro['cliente.contratos']">
            <td> {{ reg.id }} </td>

Dessa maneira deve funcionar, mas não fica legal, você passou a responsabilidade de inteirar seu array toda pro seu template.

Eu sugiro que você separe:

1 - Crie uma interface para seus registros de clientes:

export interface Registro = {
            id: string,
            dataEmissao: Date,
            menorParcela: number,
            quantidadeParcelas: number,
            agente: {
                id: number
            },
            agenteResponsavel: {
                id: number
            },
            carteira: {
                id: number,
                nome: string,
                contratoOriginal: string
            },
            valorTotal: number,
            valorDivida: number,
            valorParcela: number,
            diasAtraso: number,
            descricao: string,
            menorDataVenvcimento: Date,
            dataUltimoPagamento: Date,
            quantidadeParcelaAtrasada: number,
            taxaContrato: number,
            acordos: [{
                status: {
                    descricao: string
                },
                valor: number,
                valorEntrada: number,
                valorDivida: number,
                quantidadeParcelasAcordo: number,
                valorTotalAcordo: number
            }]
        }

export interface ContratoCobranca {
    cliente: {
        id: number,
        cpf: string,
        nome: string,
        contratos: Registro[],
        quantidadeContratos: number
    },
    status: string
}

2 - Crie uma variável para armazenar seus registros no componente:

//variavel
public registros: Registro[]: new Array<Registro>();

//codigo anterior
        result => {
            //chamada do back-end
              result.map(res => {
                res.cliente.contratos.map(r => {
                    //limpa o array de registros se houver algum
                    this.registros = new Array<Registro>();
                        this.registros.push(r);
                })
            })
        },

3 - Acesse direto no template.

<tr *ngFor="let registro of registros">
            <td> {{ registro.id }} </td>

Veja se dessa maneira funciona. Abs.