I've been trying to use an array of products that's being returned by subscribing to the corresponding service. It works fine when it comes to displaying the objects properties on a list or something similar but I've been struggling to use the Material component data-table. I tried to do it by instantiating a new MatTableDataSource with the products array as an argument and to use try dynamic datasource by using the Observable directly but no success so far, the table is empty and the console is silent.
Here is the service :
import { IProduct } from './../interfaces/IProduct';
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: "root"
})
export class ProductService {
productUrl = "https://localhost:44355/product/getproducts";
constructor(private http: HttpClient) { }
getProducts(): Observable<IProduct[]> {
return this.http.get<IProduct[]>(this.productUrl);
}
}
The TypeScript file :
import { ProductService } from './../../services/product.service';
import { Component, OnInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material';
import { IProduct } from 'src/app/interfaces/IProduct';
import { Observable } from 'rxjs';
import { DataSource } from '@angular/cdk/collections';
import 'rxjs/add/observable/of';
@Component({
selector: "app-product",
templateUrl: "./product.component.html",
styleUrls: ["./product.component.css"]
})
export class ProductComponent implements OnInit {
public products = [];
displayedColumns: string[] = ['productId', 'displayName', 'price', 'stockQuantity'];
dataSource = new ProductDataSource(this.productService);
constructor(private productService: ProductService) {}
ngOnInit() {
this.productService.getProducts()
.subscribe(
response => {
this.products = response.items;
console.log(this.products);
}
);
}
}
export class ProductDataSource extends DataSource<any> {
constructor(private productService: ProductService) {
super();
}
connect(): Observable<IProduct[]> {
return this.productService.getProducts();
}
disconnect() { }
}
And lastly the HTML
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- Position Column -->
<ng-container matColumnDef="productId">
<th mat-header-cell *matHeaderCellDef> Id </th>
<td mat-cell *matCellDef="let product"> {{product.productId}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="displayName">
<th mat-header-cell *matHeaderCellDef> Nom </th>
<td mat-cell *matCellDef="let product"> {{product.displayName}} </td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef> Prix </th>
<td mat-cell *matCellDef="let product"> {{product.price}} </td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="stockQuantity">
<th mat-header-cell *matHeaderCellDef> Quantité </th>
<td mat-cell *matCellDef="let product"> {{product.stockQuantity}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
Also I don't know if it's linked but at the subscription :
ngOnInit() {
this.productService.getProducts()
.subscribe(
response => {
this.products = response.items;
console.log(this.products);
}
);
UPDATE Incoming Data from API :
{"items":[{"productId":1,"name":"B12BocalVerreSoufflé","description":"Bocal en verre soufflé à la main et son couvercle en liège. Très bon état.","price":13.00,"status":100,"stockQuantity":1,"displayName":"Bocal en verre soufflé ","productFlags":0},{"productId":2,"name":"B30AssietteCampagne","description":"Lot de 4 assiettes en céramique. Décor en fleurs fait à la main. Bon état.","price":16.00,"status":100,"stockQuantity":36,"displayName":"Assiettes campagne ","productFlags":1},{"productId":3,"name":"B41BocalPommeHenkel","description":"Bocal en verre et couvercle en plastique. Décor pomme rouge de la marque Henkel des années 70. Bon état.","price":200.00,"status":100,"stockQuantity":11,"displayName":"Bocal pomme rouge Henkel ","productFlags":0}
And the interface IProduct :
export interface IProduct {
name: string;
price: number;
productId: number;
description: string;
status: number;
stockQuantity: number;
displayName: string;
productFlags: number;
xmlData: string;
blob: any;
}
UPDATE 2 : Stackblitz for the app : https://stackblitz.com/edit/angular-6xjfmf?embed=1&file=src/app/product.service.ts
FINAL UPDATE AND SOLUTION : So part of the solution was given by Deborah bellow, I had to use products as the datasource directly :
<table mat-table [dataSource]="products" class="mat-elevation-z8">
Also I still had the issue of not being able to get the items part of my response when subscribing, as it was considered an object and simply doing response.items wasn't working because items wasn't a property of Object.
The solution was easy I just had to do it in two steps :
ngOnInit() {
this.productService.getProducts()
.subscribe(
response => {
this.products = response;
this.products = this.products.items;
console.log(this.products);
}
);
}
There you go , I hope it helps somebody in the same situation. Thanks to Deborah!