Im trying to display data in my Angular Material Table, that I receive from my backend.
Everything works fine as long as my _timelogService.getAllTimelogs() function returns an Observable of dummy data which I hard coded into the function. As soon as I make an actualy HTTP POST request to my backend - and return an Observable of that data - the html table doesnt display any rows eventhough my dataSource contains the required data.
When I use logData()
it display the correct data even if i use the actual Observable.
I suspect that my Angular Table does not get updated when the dataSource gets updated.
Did anyone else ever encounter such an issue?
export class OverviewComponent implements OnInit {
displayedColumns: string[] = ['roomId', 'startTime', 'endTime',
'duration'];
dataSource = new MatTableDataSource<TimeLogTable>();
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@ViewChild(MatSort, { static: true }) sort: MatSort;
constructor(private _timelogService: TimelogService) {
//In the Docs example the dummy data gets created here
}
ngOnInit(): void {
this._timelogService.getAllTimelogs().subscribe(
dataObs=>{
console.log("Display received data");
console.log(dataObs);
this.dataSource.data = dataObs;
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
)
}
logData(){
console.log(this.dataSource);
}
}
My Service
getAllTimelogs(): Observable<TimeLogTable[]>{
var timelogsArr: TimeLogTable[] = [];
var timelogsArrDummy: TimeLogTable[] = [];
//Call to backend
this._http.get<any>('http://localhost:3000/gettimelogs?token=' +
localStorage.getItem('token'), this.httpOptions)
.subscribe(
res=>{
//Create timeLogTable from json with backend response
for (let i = 0; i < res.timelogs.length; i++) {
timelogsArr.push({
roomId: res.timelogs[i].roomId,
startTime: new Date(res.timelogs[i].startTime),
endTime: new Date (res.timelogs[i].endTime),
duration: "test"
});
}
},
err=>{
//Error handling
}
);
//Return the Observable - DOES NOT WORK
return of (timelogsArr);
/*
//Return the dummy data as an Observable - DOES WORK
//Dummy data
timelogsArrDummy = [
{roomId: 'kit_A', startTime: new Date(1631185600000), endTime: new
Date (1631185661311), duration: "test"},
{roomId: 'din_A', startTime: new Date(1631185600000), endTime: new
Date (1631195661311), duration: "test"},
{roomId: 'off_A', startTime: new Date(1631185600000), endTime: new
Date (1632185661311), duration: "test"},
{roomId: 'kit_B', startTime: new Date(1631185600000), endTime: new
Date (1631885661311), duration: "test"},
]
return of (timelogsArrDummy);
*/
}
I found the issue that was causing my problem. My getAllTimelogs() function returned an empty Object first and then filled it up with data later. The MatTableDataSource somehow could not handle that. Here is my working code:
export class OverviewComponent implements OnInit, AfterViewInit {
displayedColumns: string[] = ['roomId', 'startTime', 'endTime', 'duration'];
dataSource = new MatTableDataSource<TimeLogTable>();
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@ViewChild(MatSort, { static: true }) sort: MatSort;
constructor(private _timelogService: TimelogService) { }
timelogsArr: TimeLogTable[] = [];
ngOnInit(): void {
this._timelogService.getAllTimelogs().subscribe(
res=>{
//Create timeLogTable from json with backend response
console.log("alert");
for (let i = 0; i < res.timelogs.length; i++) {
//Change the format of the data
this.timelogsArr.push({
roomId: res.timelogs[i].roomId,
startTime: new Date(res.timelogs[i].startTime),
endTime: new Date (res.timelogs[i].endTime),
duration: this.msToTime(res.timelogs[i].endTime - res.timelogs[i].startTime)
});
}
//Update table datasource
this.dataSource.data = this.timelogsArr;
}
);
}
ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
And here the getAlltimelogs()
function:
getAllTimelogs(): Observable<any>{
return this._http.get<any>('http://localhost:3000/gettimelogs?token=' + localStorage.getItem('token'), this.httpOptions)
}
Thanks to everyone who kindly helped me.