i'm trying to build a movie watchlist table for a project. The problem is that, when i get my array of data from firebase, i create a MatTableDataSource and attribute it the array i received, but i don't get any output on screen. How do i fix this ? Do i need to call a reload function ?
Example of what the page shows : https://imgur.com/a/X0aubfw
main-page-component.ts
import { Component, OnInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { Movie } from 'src/app/core/models/movie';
import { MovieService } from 'src/app/core/services/movie.service';
@Component({
selector: 'app-main-page',
templateUrl: './main-page.component.html',
styleUrls: ['./main-page.component.scss']
})
export class MainPageComponent implements OnInit {
movieData: MatTableDataSource<Movie>;
displayedColumns: string[] = ['title', 'genre', 'watchStatus', 'rating', 'wouldRecommend'];
constructor(private movieService: MovieService) { }
async getMoviesOfUser() {
let resultData : Movie[] = this.movieService.getAllMoviesOfUser("1W43qABYx3WAdcrpL2cz");
this.movieData = new MatTableDataSource(resultData);
}
ngOnInit(): void {
this.getMoviesOfUser();
console.log(this.movieData.data);
}
}
main-page-component.html
<div >
<p id="toolbar-top">
<mat-toolbar color="primary">
Welcome (de pus numele userului aici)
<button mat-icon-button id="logout-icon">
<mat-icon>logout</mat-icon> Logout
</button>
</mat-toolbar>
</p>
<table mat-table [dataSource]="movieData" >
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef> Title </th>
<td mat-cell *matCellDef="let element"> {{element.title}} </td>
</ng-container>
<ng-container matColumnDef="genre">
<th mat-header-cell *matHeaderCellDef> Genre </th>
<td mat-cell *matCellDef="let element"> {{element.genre}} </td>
</ng-container>
<ng-container matColumnDef="watchStatus">
<th mat-header-cell *matHeaderCellDef> Status </th>
<td mat-cell *matCellDef="let element"> {{element.watchStatus}} </td>
</ng-container>
<ng-container matColumnDef="rating">
<th mat-header-cell *matHeaderCellDef> Rating </th>
<td mat-cell *matCellDef="let element"> {{element.rating}} </td>
</ng-container>
<ng-container matColumnDef="wouldRecommend">
<th mat-header-cell *matHeaderCellDef> Recommended ? </th>
<td mat-cell *matCellDef="let element"> {{element.wouldRecommend}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
movie-service.ts
import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/compat/firestore';
import { Movie } from '../models/movie';
@Injectable({
providedIn: 'root'
})
export class MovieService {
moviesRef = this.database.collection('Movies');
constructor(private database: AngularFirestore) { }
getAllMoviesOfUser(userID: string) {
let result: any[] = [];
this.moviesRef.ref.where('includedBy', '==', userID).get().then((querySnapshot) => {
querySnapshot.forEach((doc) => result.push(doc.data()));
});
return result;
}
}
movie interface
export interface Movie {
includedBy : string;
title : string;
genre : string;
watchStatus : string;
rating : string;
wouldRecommend : string;
}
CodePudding user response:
First of all I would recomend you to add return types to a methods. It will help you.
second. in component you have async, but where is await?
third. in service you have asyncroneous request to db. but you return result before the request is fullfilled. so you have empty array.
problem not in mat-table. problem in obtaining data from service.
try this
async getMoviesOfUser() {
let resultData : Movie[] = await this.movieService.getAllMoviesOfUser("1W43qABYx3WAdcrpL2cz");
this.movieData = new MatTableDataSource(resultData);
}
and in service something like this
async getAllMoviesOfUser(userID: string) {
const snapShots = await this.moviesRef.ref.where('includedBy', '==', userID).get();
return snapShots.map(item => item.data());
}