0

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!

jeeves
  • 105
  • 1
  • 4
  • You need to show how you're obtaining the values from the backend. **Not** the actual data, but how you are trying to obtain it. – ruth Aug 19 '20 at 12:16

2 Answers2

2

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.

ruth
  • 29,535
  • 4
  • 30
  • 57
0

Try this

  ngOnInit() {
    this.data
      .getBooks()
      .pipe(
        filter((data) => !!data),
        map((data: any[]) => {
          data.map((item: any) => {
            if (item.fine != 0) {
              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,
              };
            }
          });
        })
      )
      .subscribe((books: BooksData) => {
        this.dataSourceBook = new MatTableDataSource(books);
        this.dataSourceBook.paginator = this.paginator;
        this.dataSourceBook.sort = this.sort;
      });
  }