I am building a simple webshop app in Angular and I want to represent products I get thru the service in an Angular Material Table. I have a Product interface:
export interface Product {
id: number;
name: String;
price: number;
}
I have a products.json in my assets folder. In my service class have getProducts() method that reaches back to the json (in the future possibly to a more distant backend):
private products_url = "/assets/data/products.json";
public getProducts(): Observable<Product[]> {
//return this.http.get<Product[]>(`${this.apiServerUrl}/product/all`);
return this.http.get<Product[]>(this.products_url);
}
In my component class I have a getProducts() function that reaches out to the service:
public getProducts(): void {
this.canteenService.getProducts().subscribe(
(response: Product[]) => {
this.products = response;
},
(error: HttpErrorResponse) => {
alert(error.message);
}
)
}
When I want to declare the dataSource for the Material Table in a way that it gets the products thru this getProducts() function in the component, I get an error.
public dataToDisplay = this.getProducts();;
public dataSource = new ExampleDataSource(this.dataToDisplay);
The error says: Argument of type 'void' is not assignable to parameter of type 'Product[]'.ts(2345)
How can I fix this?
CodePudding user response:
You need know how work an Observable. An Observable is asyncronous. So you don't get the response else inside subscribe function. So you need
dataSource:MatDataSource<any> //outside you declare the variable
public getProducts(): void {
this.canteenService.getProducts().subscribe(
(response: Product[]) => {
this.products = response;
//here asign the matDataSource
this.dataSource = new MatDataSource(this.dataToDisplay);
},
(error: HttpErrorResponse) => {
alert(error.message);
}
)
}
BTW, if you don't need sort or paginate, the data source of a mat-table can be an array, so you can use async pipe
dataSource$=this.canteenService.getProducts() //<--see that is an observable
<table mat-table [dataSource]="dataSource$ |async">
...
</table>
NOTE: By defect all the variables of a component you declare are public, so it's unnecessary use public variable:any
-you can declare as variable:any
-
CodePudding user response:
Your function getProducts()
from your component doesn't return anything, you even set the return type as void
, also, the naming convention for this particular function is wrong since you are not get
ting anything
I suggest you do the following:
getProducts$(): Observable<Product[]> {
return this.canteenService.getProducts();
}
<table [dataSource]="getProducts$()">
<...>
</table>