Issue
I am having problem when implementing a form in Angular Material, the delProduct()
function does not work, neither does the editProduct()
function.
The getProducts()
function obtains the complete array (including the ID),
Adding a console log of the complete element to the delProduct()
function gets the complete array, but without the id.
code list-products.components.ts
export class ListProductsComponent implements OnInit {
productos: any[] = [];
dataSource: MatTableDataSource<any>;
displayedColumns: any[] = [
'cantidad',
'nombre',
'ubicacion',
'categoria',
'subcategoria',
'moneda',
'precio',
'action'
];
@ViewChild(MatPaginator)
paginator!: MatPaginator;
@ViewChild(MatSort)
sort: MatSort = new MatSort;
constructor(private _ProductService: ProductService,
private afs: AngularFirestore) {
this.dataSource = new MatTableDataSource(this.productos);
}
ngOnInit(): void {
this.getProducts();
}
ngAfterViewInit() {
this.afs.collection('productos', ref=> ref.orderBy('fechaCreacion', 'desc')).valueChanges().subscribe(data => {
this.dataSource = new MatTableDataSource(data);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
})
}
getProducts() {
this._ProductService.getProducts().subscribe(data => {
this.productos = [];
data.forEach((element:any) => {
this.productos.push({
id: element.payload.doc.id,
...element.payload.doc.data()
})
})
console.log(this.productos);
});
}
delProduct(element: any, index: any) {
// const data = this.dataSource.data;
// data.splice((this.paginator.pageIndex * this.paginator.pageSize) + index, 1);
// this.dataSource.data = data;
// this._ProductService.delProduct(element.id)
console.log('ID', element.id)
}
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
}
Code list-products.component.html (items are displayed normally, only I have problems with edit / delete functions)
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef> Action </th>
<td mat-cell *matCellDef="let element; let i = index">
<mat-icon [routerLink]="['/edit-product/', element.id]">edit</mat-icon>
<mat-icon (click)="delProduct(element, i)">delete</mat-icon>
</td>
</ng-container>
code product.service.ts
export class ProductService {
constructor(private firestore: AngularFirestore){ }
getProducts(): Observable<any>{
return this.firestore.collection('productos', ref=> ref.orderBy('fechaCreacion', 'desc')).snapshotChanges();
}
delProduct(id: string): Promise<any>{
return this.firestore.collection('productos').doc(id).delete();
}
editProduct(id: string, data:Product): Promise<any>{
return this.firestore.collection('productos').doc(id).update(data);
}
}
Solution
You’re reading data twice. Once with ids (using snapshotChanges) and once without ids (using valueChanges).
I suggest putting an id field directly inside every document. It makes everything easier.