Angular: Effective communication between components through routing and Observable binding ultimately results in the advancement of ngtsc(233

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.

Answer №1

If you have an Observable that needs to be displayed, make sure to utilize the async pipe:

<mat-card-subtitle>Brand: {{(selectedProduct|async)?.brand}}</mat-card-subtitle>

This will subscribe to the selectedProduct and show the value of the brand attribute.

Alternatively, you can assign it to a local variable with a proper name:

*ngIf="selectedProduct | async as product"

Then use it within the HTML block:

 <mat-card-subtitle>Brand: {{product?.brand}}</mat-card-subtitle>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The serverTimeStamp() function in firebase.firestore.FieldValue does not allow for the Timestamp data type to be used

async addNewUser(id: string, email: string) { await this.afs.doc<MemberProfileModel>(FirestoreDbConstant.MEMBER_PROFILES + `/${id}`).set({ email, registeredDate: firebase.firestore.FieldValue.serverTimestamp(), }); } This appro ...

How can you eliminate the first elements of two or more arrays of objects until all of their first elements match based on a specific field?

My Typescript code includes a Map object called `stat_map` defined as const stat_map: Map<string, IMonthlyStat[]> = new Map(); The interface IMonthlyStat is structured as shown below (Note that there are more fields in reality) export interface IMon ...

What is the reason behind the inability of the Angular/TypeScript HTTP GET method to accept a JSON object as a parameter

EXAMPLE 1 passJSONObj(){ let name = 'user names', let email = '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d7a2a4b2a5b2bab6bebb97b3b8bab6beb9f9b2afa3">[email protected]</a>&ap ...

Issue: fs.js:47 } = primordials; ^ ReferenceError: primordials is not defined - Please handle this error

I encountered an issue where my node version is 12.11.1, however when I try running the command npm run server, it returns an error message as displayed below: fs.js:47 } = primordials; ^ ReferenceError: primordials is not defined at fs.js:47:5 ...

When utilizing Ionic Firebase, the user profile saved in the sidemenu is stored using the Events class. However, the saved profile disappears as soon as

Hello there. I am currently working on displaying my user's information in the sidemenu, and after some research, I found that using the Events class might solve this issue. However, I have noticed that the data saved in subscribe gets destroyed whene ...

unable to select date on mat-calendar

I'm trying to add special dates to a mat-calendar by highlighting them. Here's the code I have so far: app.component.ts: datesToHighlight = ["2019-06-22T18:30:00.000Z", "2019-06-06T18:30:00.000Z", "2019-06-24T18:30:00.000 ...

This element is not suitable for use as a JSX component since its return type 'void' is not a valid JSX element. Please check the return type to ensure it is compatible with

I have been working on this code snippet: function searchData(searchWord: any) { if (originalData.length > 0) { if (searchWord !== "") { setDataList([...originalData.filter((svc: any) => ...

Automatically expanding PrimeNG Turbotable rows

I am using a PrimeNg turbotable that has a row expansion feature enabled. I am looking for a way to automatically expand the rows by default when the table loads. Shown below is my code: HTML <p-table [columns]="cols" [value]="cars" dataKey="vin"> ...

Creating a data structure that filters out specific classes when returning an object

Consider the following scenario: class MyClass {} class MyOtherClass { something!: number; } type HasClasses = { foo: MyClass; bar: string; doo: MyClass; coo: {x: string;}; boo: MyOtherClass; }; type RemovedClasses = RemoveClassTypes& ...

Deactivate the selection option in Syncfusion NumericTextbox

I have integrated an Angular NumericTextbox component from Syncfusion into my application. A problem we encountered is that when the input is clicked, it automatically gets selected. Is there a way to disable this behavior? Problem: https://gyazo.com/a72b ...

Blending TypeScript declaration files and Node.js require across various files within an internal module

Is it problematic to mix Node.js modules (require) with TypeScript definition files (d.ts) multiple times within a module? In my case, I organize my modules into namespaces per folder similar to how it's done in C#. After compiling them all using tsc ...

Can optional properties or defaults have a specific type requirement defined for them?

When defining a type for a function's input, I want to designate certain properties as required and others as optional: type Input = { // Required: url: string, method: string, // Optional: timeoutMS?: number, maxRedirects?: number, } In ...

Constantly visible scrolling feature on material side navigation

Is there a way to keep the scroll bar in the sidenav always visible, even when the content is within the Y axis limits? This would prevent the scroll bar from fading in and out every time I open or close one of the mat-menu-items that function as accordio ...

Exploring the world of nested observables in Angular through cascading HTTP requests

My plan involves the following steps: Make a request to https://reqres.in/api/users/2 This request will return the following response. { "data": { "id": 2, "first_name": "Janet", "last_name": "Weaver", "avatar": "https://s3.ama ...

Convert the XML response from an API into JSON

Is there a way to convert my XML response into JSON using Angular? This is the response I am working with: <?xml version="1.0" encoding="utf-8"?> <string xmlns="http://tempuri.org/"><?xml version="1.0" encoding="utf-8"?&gt; &lt;Fer ...

Creating a merged object from a split string array in TypeScript

I possess an array containing objects structured as follows; const arr1 = [ {"name": "System.Level" }, {"name": "System.Status" }, {"name": "System.Status:*" }, {"name": "System.Status:Rejected" }, {"name": "System.Status:Updated" } ] My object ...

Changing a "boolean bit array" to a numerical value using Typescript

Asking for help with converting a "boolean bit array" to a number: const array: boolean[] = [false, true, false, true]; // 0101 Any ideas on how to achieve the number 5 from this? Appreciate any suggestions. Thanks! ...

Is there a way to specify a type for a CSS color in TypeScript?

Consider this code snippet: type Color = string; interface Props { color: Color; text: string; } function Badge(props: Props) { return `<div style="color:${props.color}">${props.text}</div>`; } var badge = Badge({ color: &ap ...

What is the best way to combine data from two rows into one row?

Can someone help me with merging 2 sets of Line data into a single row for each entry? For example, the 'Green Bay Packers @ Chicago Bears' row should display '+3.5000 and -3.5000', while 'Atlanta @ Minnesota' should show &apo ...

calculate the difference between two dates and then add this difference to a new date

Utilizing TypeScript for date calculations. Example: Initial Date 1: "10/06/2021 10:10:05" Initial Date 2: "08/06/2021 11:10:05" Calculate the difference between the two dates, including date/month/year/hour/min/sec/milliseconds. Ensure compatibility wi ...