I designed an Angular Component named "crear-pedido" that exhibits a catalog of items (using row of products) and my aim is for the user to have the ability to click on the values in the ID column and navigate the application to a subordinate component known as "detalle-productos". Essentially, it's a list of products where if you click on the product.ID, a card pops up revealing the specifics of the product.
Relevant routing configuration:
const routes: Routes = [
{ path: 'crear-pedido', component: CrearPedidoComponent,
children: [
{path: ':ID', component: DetalleProductosComponent},
]},
];
I am sending the row.ID data to the child component like this:
<td mat-cell *matCellDef="let row"><a [routerLink]="['/crear-pedido', row.ID]"> {{row.ID}} </a> </td>
This is the "detalle-productos.component.ts" file:
import { Component, OnInit } from '@angular/core';
import { Producto_interface } from '../producto_interface';
import product_list from '../product_json.json'
import { ActivatedRoute } from '@angular/router';
import { Observable, switchMap } from 'rxjs';
@Component({
selector: 'app-detalle-productos',
templateUrl: './detalle-productos.component.html',
styleUrls: ['./detalle-productos.component.css']
})
export class DetalleProductosComponent implements OnInit {
productos: Producto_interface [] = product_list;
selectedProduct: Observable<Producto_interface>;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.selectedProduct = this.route.paramMap.pipe(
switchMap(params => {
const id = params.get('ID');
console.log("Inside oninit")
console.log(this.productos.filter(p => p.ID.toString() == id?.toString()))
return this.productos.filter(p => p.ID.toString() == id?.toString())
})
)
}
}
As you can see, the component retrieves the JSON file containing all the products in "product_list" and the ngOnInit() method takes in the routed value and refines the product_list to locate the correct product. The objective is to transmit the product information to selectedProduct and then present that in the HTML.
The console.log right before the return statement functions correctly:
0: Object { ID: "606", Nombre: "Tapitas Gran Valle Galleta Blanca 9 KG", Linea: "Tapitas", … }
Here is the pertinent HTML:
<mat-card class="product-card" *ngIf="selectedProduct | async as Producto_interface">
<mat-card-subtitle>Marca: {{selectedProduct['Marca']}}</mat-card-subtitle>
<mat-card-title>{{selectedProduct['Nombre']}}</mat-card-title>
<mat-card-content>
<p>Código interno: {{selectedProduct['ID']}}</p>
<p>Sabor: {{selectedProduct['Sabor']}}</p>
<p>Envase: {{selectedProduct['Envase']}}</p>
<p>Línea: {{selectedProduct['Linea']}}</p>
</mat-card-content>
<button mat-raised-button routerLink="/crear-pedido" color="primary">Cerrar</button>
</mat-card>
The issue is when you tap on the ID, the card emerges but it is entirely empty.
I am relatively new to Angular and struggling with deciphering the whole Observable<> and strict types maze. I had to add:
"noImplicitAny": false,
To the tsconfig.json file to get it to compile. I'm quite certain that the correct syntax should be:
selectedProduct.Marca
Instead of selectedProduct['Marca']
However, doing so triggers the following error:
Property 'Marca' does not exist on type 'Observable<Producto_interface>'.ngtsc(2339)
I've browsed through around a dozen different threads concerning similar issues, yet after testing every solution, this is the extent of my progress.
Please assist me, Stackoverflowers. You are my sole hope.