1
resposta

Angular Material Table

Estou com um problema para montar um tipo de tabela usando o angular material table: Preciso que as info que pego de uma API sejam o Header da minha table e seus valores sejam a linha respectiva de cada header. Ex: Tenho um array de chaves [{chave: 'ABC', valor: 20}, {chave: 'DEF', valor: 30}, {chave: 'HIJ', valor: 50} ]. Preciso que na tela apareça assim:

ABCDEFHIJ
203050

Como faço, atualmente estou utilizando dessa forma no html:

<table mat-table [dataSource]="dataSource">
  <ng-container [matColumnDef]="column" *ngFor="let column of displayedColumns">
    <th mat-header-cell *matHeaderCellDef>{{ column }}</th>
    <td mat-cell *matCellDef="let element">{{ element.valor}}</td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

mas dessa forma está aparecendo desse jeito:

ABCDEFHIJ
202020
303030
505050

Preciso saber como ajusto isso;

Obrigado.

1 resposta

Olá, Fernando, tudo bem?

Com base no código que você compartilhou, o problema que você está enfrentando está relacionado à repetição dos valores na tabela, resultando em uma exibição incorreta. Para resolver essa questão, você precisa ajustar a estrutura do seu código para que cada chave seja exibida apenas uma vez no cabeçalho da tabela, e seus valores correspondentes sejam exibidos nas células de cada linha.

O problema está ocorrendo porque a variável dataSource está contendo as seguintes informações:

dataSource = [
  { chave: 'ABC', valor: 20 },
  { chave: 'DEF', valor: 30 },
  { chave: 'HIJ', valor: 50 }
];

E a variável displayedColumns contém apenas os nomes das chaves:

displayedColumns = ['ABC', 'DEF', 'HIJ'];

O que acontece é que, na sua iteração com *ngFor, para cada coluna, você está exibindo repetidamente os valores de element.valor, o que não é o comportamento desejado.

Para corrigir isso, você precisa estruturar seus dados de forma diferente. Primeiramente, é necessário transpor as informações da API para que cada chave se torne uma coluna e os valores sejam as linhas correspondentes. Uma abordagem possível é transformar o seu dataSource em um objeto que tenha as chaves como propriedades e os valores como seus respectivos valores. Algo assim:

dataSource = {
  'ABC': 20,
  'DEF': 30,
  'HIJ': 50
};

Para fazer essa transformação, você pode utilizar a função reduce em JavaScript/TypeScript. Veja como ficaria:

// Supondo que você já tem o array original da API em 'data'
const dataSource = data.reduce((acc, item) => {
  acc[item.chave] = item.valor;
  return acc;
}, {});

Agora, você precisa ajustar o seu template (HTML) para iterar sobre as chaves do objeto dataSource e exibir seus valores correspondentes. Para isso, você pode utilizar o seguinte código:

<table mat-table [dataSource]="dataSource">
  <ng-container *ngFor="let column of displayedColumns" [matColumnDef]="column">
    <th mat-header-cell *matHeaderCellDef>{{ column }}</th>
    <td mat-cell *matCellDef="let element">{{ dataSource[column] }}</td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

Agora, a tabela será renderizada corretamente, mostrando cada chave apenas uma vez no cabeçalho e os valores correspondentes nas células de cada linha.

Espero que essa explicação tenha sido clara e que tenha ajudado a resolver o problema com a exibição da tabela. Se tiver mais dúvidas, fique à vontade para perguntar. Bons estudos!

E só como um lembrete, como eu não tenho o código completo, talvez minha solução pode não ser tão assertiva, mas você pode seguir nessa linha de raciocínio para resolver o problema. Creio que já é um bom começo.

Espero que tenha te ajudado, caso precise de eu estarei por aqui.

Abraços e bons estudos!