I am having trouble with populating matTableDataSource on startup. On startup I get empty table with *matNoDataRow message. When I click sort on any column or type anything in filter input, the data appears immediately.
I tried to use hardcoded values for table rows and it works fine. Everything is loaded on startup. I have a working stackblitz example here where I copied everything except subscription, because it gets values from my database: StackblitzExampleOfHardcodedArray
I also tried to populate array in service and call it in component after (done) but it also did not show the rows.
Here is my original method
parseUserData: any;
returnValue: any = [];
getAllBooksFromDatabase() : BooksData[] { //all books from Bookshelf
this.returnValue.splice(0, this.returnValue.length);
this.data.getBooks().subscribe((data: any) => {
this.parseUserData = JSON.parse(JSON.stringify(data));
this.parseUserData.map((item:any) => {
if(item.fine != 0){
this.returnValue.push(
{
uid: item.uid,
bid: item.bid,
bookTitle: item.bookTitle,
authorLastName: item.authorLastName,
authorFirstName: item.authorFirstName,
issuedDate: item.issuedDate,
period: item.period,
fine: item.fine,
warning: item.warning
}
);
}
})
return this.returnValue;
}
EDIT: this is my service method for obtaining data
public getBooks(): Observable<any> {
return this.http.get('http://localhost:8080/books')
.pipe(map((books: any) => books));
}
EDIT: and this is part of result - books:
[
{
"warning": "",
"issuedDate": "in library",
"period": "0",
"bookTitle": "Balade Petrice Kerempuha",
"bid": "158744286",
"fine": "0",
"authorLastName": "Krleža",
"authorFirstName": "Miroslav",
"bookGenre": "poetry",
"uid": ""
},
{
"warning": "",
"issuedDate": "in library",
"period": "0",
"bookTitle": "Na rubu pameti",
"bid": "653621302",
"fine": "0",
"authorLastName": "Krleža",
"authorFirstName": "Miroslav",
"bookGenre": "poetry",
"uid": ""
},
{
"warning": "",
"issuedDate": "in library",
"period": null,
"bookTitle": "Kule u zraku",
"bid": "746388428",
"fine": null,
"authorLastName": "Larsson",
"authorFirstName": "Stieg",
"bookGenre": "triler",
"uid": null
},
{
"warning": "",
"issuedDate": "borrowed",
"period": "1",
"bookTitle": "U zemlji klanova",
"bid": "542455118",
"fine": "0",
"authorLastName": "Rudan",
"authorFirstName": "Igor",
"bookGenre": "popularization of science",
"uid": "0231027834"
},
{
"warning": "",
"issuedDate": "borrowed",
"period": "1",
"bookTitle": "Točna boja neba",
"bid": "542455578",
"fine": "0",
"authorLastName": "Rudan",
"authorFirstName": "Igor",
"bookGenre": "popularization of science",
"uid": "0231027834"
},
{
"warning": "",
"issuedDate": "in library",
"period": "0",
"bookTitle": "Očekujući vatre",
"bid": "548754578",
"fine": "0",
"authorLastName": "Rudan",
"authorFirstName": "Igor",
"bookGenre": "popularization of science",
"uid": ""
},
{
"warning": "",
"issuedDate": "in library",
"period": "0",
"bookTitle": "Zao zrak",
"bid": "548755578",
"fine": "0",
"authorLastName": "Rudan",
"authorFirstName": "Igor",
"bookGenre": "popularization of science",
"uid": ""
}
]
How can I show all table rows on startup? Any advice is welcome. Thanks in advance!
The this.returnValue
variable is assigned asynchronously. So by the time you're returning it, it's still empty. You could instead modify your data using RxJS map
operator along with Array map
and filter
functions and assign it directly in the ngOnInit
hook.
Try the following
ngOnInit() {
this.getAllBooksFromDatabase().subscribe(
books => {
this.dataSourceBook = new MatTableDataSource(books);
this.dataSourceBook.paginator = this.paginator;
this.dataSourceBook.sort = this.sort;
}
);
}
getAllBooksFromDatabase(): Observable<BooksData[]> { // all books from Bookshelf
return this.data.getBooks().pipe(
map(data => {
return data
.filter(item => item.fine != 0) // <-- your condition
.map(item => {
return {
uid: item.uid,
bid: item.bid,
bookTitle: item.bookTitle,
authorLastName: item.authorLastName,
authorFirstName: item.authorFirstName,
issuedDate: item.issuedDate,
period: item.period,
fine: item.fine,
warning: item.warning
}
})
})
);
}
More info on async data here.