[Fixed] TypeError: data.slice is not a function Angular

Issue

I am working with a JSON file with topic modeling data:

JSON

[{"message": "Cygnus olor is a large bird with a majestic white coat, brazingly orange beak and a black knob on their bill that is larger in males." , 
"messageTopic": 0, 
"contributionPercent": 0.9901618361473083},
{"message": "The quick brown fox jumped over the lazy dog", 
"messageTopic": 1, 
"contributionPercent": 0.981721043586731}]

I am trying to display this information in an Angular material table.

Typescript

import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';
import { ActivatedRoute } from '@angular/router';
import { TopicDocumentDatum } from './topic-document-table-types';

@Component({
  selector: 'amm-topic-document-table',
  templateUrl: './topic-document-table.component.html',
  styleUrls: ['./topic-document-table.component.scss']
})
export class TopicDocumentTableComponent implements OnInit, AfterViewInit {
  dataSource: MatTableDataSource<TopicDocumentDatum>;
  @ViewChild(MatPaginator) paginator: MatPaginator;

  displayedColumns: string[] = [
    'messageTopic',
    'message',
    'contributionPercent'
  ];

  constructor(private route: ActivatedRoute) { }

  ngOnInit(): void {
    this.route.data.subscribe(
      (data: TopicDocumentDatum[]) => {
        this.dataSource = new MatTableDataSource(data);
        console.log(data); // just to see if the data is being passed through
      });
  }

  ngAfterViewInit(): void {
    this.dataSource.paginator = this.paginator;
  }

}

HTML

<div class="container" fxLayout="row" fxLayoutGap="15px" fxLayoutAlign="center center">
    <div id="topics-document-table" class="mat-elevation-z8">
        <table mat-table [dataSource]="dataSource">
            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
            <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

            <ng-container matColumnDef="messageTopic">
                <th mat-header-cell *matHeaderCellDef> Topic </th>
                <td mat-cell *matCellDef="let row"> {{row.messageTopic}} </td>
            </ng-container>

            <ng-container matColumnDef="message">
                <th mat-header-cell *matHeaderCellDef> Text </th>
                <td mat-cell *matCellDef="let row"> {{row.message}} </td>
            </ng-container>

            <ng-container matColumnDef="contributionPercent">
                <th mat-header-cell *matHeaderCellDef> Contribution Percent </th>
                <td mat-cell *matCellDef="let row"> {{row.contributionPercent}} </td>
            </ng-container>
            
        </table>
        <mat-paginator class="mat-paginator-sticky" [pageSizeOptions]="[10, 20]" showFirstLastButtons></mat-paginator>
    </div>
</div>

When I run this, I get an error: ERROR TypeError: data.slice is not a function printed in the console and the reference is to my typescript code this.dataSource.paginator = this.paginator. I’ve checked to ensure that the data being passed in is an array, the console output is: Object { topicDocumentTableData: (200) [...] }. When I expand this, the array that I passed in appears, so I believe that the data is being passed in correctly. So, I’m honestly not sure what I’m doing wrong here. Any help is great appreciated!

Solution

The MatTableDataSource accepts an array not an object.

You have to set:

this.dataSource = new MatTableDataSource(data.topicDocumentTableData);

Leave a Reply

(*) Required, Your email will not be published