Angular2 ngFor, encountering undefined property

Having an issue where one of my properties is showing as "undefined" even though it is defined. Can't seem to find a solution:

I have a parent component with the following data:

    @Component({
      selector: "app-my-products",
      templateUrl: "./my-products.component.html",
      styleUrls: ["./my-products.component.css"]
    })
    export class MyProductsComponent implements OnInit {
      watched: WatchedProduct[] = [];
      products: Product[] = [];
      watchedProducts: Product[] = [];
      ratings: ProductAvarageRating[] = [];
//the data retrieval works fine

In Parent.Component.html, I call two child components like this, passing in the data:

<div>
        <app-my-products-ratings
              [watchedProducts]="watchedProducts"
              [ratings]="ratings"
            ></app-my-products-ratings>

            <app-my-products-watched
              [watchedProducts]="watchedProducts"
            ></app-my-products-watched>
</div>

MyProductsWatched.component.ts has the following structure:

@Component({
  selector: "app-my-products-watched",
  templateUrl: "./my-products-watched.component.html",
  styleUrls: ["./my-products-watched.component.css"]
 })
export class MyProductsWatchedComponent implements OnInit {
  products: Product[] = [];
  watched: WatchedProduct[] = [];
  selectedProduct = new Product();
  @Input() watchedProducts: WatchedProduct[] = []; //data from Parent here

And its html looks like this:

<mat-list-item *ngFor="let product of watchedProducts">
    <button mat-button>{{ product.name }}</button>
</mat-list-item>

This part works fine. However, in MyProductRatings.component.html, I encounter an error where one of the properties from ratings is undefined.

The Component for MyProductRatings is structured as follows:

@Component({
  selector: "app-my-products-ratings",
  templateUrl: "./my-products-ratings.component.html",
  styleUrls: ["./my-products-ratings.component.css"]
 })
export class MyProductsRatingsComponent implements OnInit {
   @Input() watchedProducts: WatchedProduct[] = [];
   @Input() ratings: ProductAvarageRating[] = []; //data from parent here

The corresponding HTML is:

<div>
  <mat-selection-list>
    <mat-list-item
      *ngFor="
        let product of (watchedProducts | search: searchText);
        let i = index
      "
    >
      <button mat-button>{{ watchedProducts[i].name }}</button>
      {{ ratings[i].avarageRating }}
    </mat-list-item>
  </mat-selection-list>
</div>

My goal is to fetch the property named avarageRating from ratings based on the index during the *ngFor loop.

Currently, I have 2 items in watchedProducts. The error message in MyProductRatings.component.html reads:

ERROR TypeError: Cannot read property 'avarageRating' of undefined

Despite this error, the rating actually displays correctly.

My question is, what am I doing wrong that is causing these errors to appear in the console?

Answer №1

Your watchedProducts appear before averageRating in the code. To ensure that averageRating loads before watchedProducts, consider adjusting the way you load the data or simply add a *ngIf="ratings[i]" to make it more like:

<span> *ngIf="ratings[i]">{{ ratings[i].averageRating }} </span>

It's recommended to opt for the latter option as it addresses any issues that may arise if the number of ratings does not match the number of watchedProducts. This approach will help prevent an index out of bounds error.

Answer №2

When iterating over the watchedProducts array and attempting to retrieve a value from the ratings array based on its index, it is important to anticipate different scenarios. For instance, if the watchProducts array contains more items than the ratings array, an out of range exception may occur. Similarly, if the ratings array has no items at all, you could encounter a 'Cannot get property of undefined' error. Therefore, it is advisable to ensure that the ratings array has a value before accessing it.

To address this issue, you can replace {{ ratings[i].averageRating }} with the following:

      {{ GetAverageRatings(i) }}

In your component.ts file, you can define the function as shown below:

GetAverageRatings(index:number)
{
if(this.ratings[index])
{
return this.ratings[index];
}
}

Thank you.

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

Learn the process of importing third-party vendor node modules along with their sub dependencies in Angular 2 using angular-cli

Looking to load a more complex node module in an Angular 2 project bootstrapped with angular-cli? The wiki has instructions for loading a single node module, but what about modules with multiple dependencies like angular2-apollo? For example, angular2-apo ...

I am facing difficulties in including a new component using Angular CLI within an ASP.NET Core Single Page Application

Looking to incorporate a new component into my asp.net core 2.0 SPAs using angular 4 and angular cli. Here are the versions I'm working with: @angular/cli: 1.4.2 node: 8.4.0 os: Linux x64 Encountered an error when running ng g c vehicle-form on a ...

Nested Tagged Union Types in Typescript

Imagine having the following types (syntax similar to Elm/Haskell): type Reply = LoginReply | LogoutReply type LoginReply = LoginSucceeded | AlreadyLoggedIn String When trying to represent this in Typescript using discriminated unions, a challenge arises ...

Setting up an angular2 web application on an Nginx server and forwarding HTTP requests to the backend API for

Seeking assistance with setting up angular2 routes and proxying http requests to a rest api on a separate server Currently, I have an angular2 web application running on an nginx server which serves the static html files. The rest api that the application ...

Transmitting data from Angular to .NET Core for seamless integration

I have been attempting to send an xls or any other file from my angular application to a .NET core controller, but none of my methods seem to work... Below is my component where I call my service upon button click: handleFileInput(file: FileList) { this. ...

What is the best way to exhibit information from a lone table column in a modal using Angular 7?

Is there a way to have an "edit" button beside each row in the appointments table that triggers a modal popup allowing users to change appointment dates? Unfortunately, I'm facing an issue where the modal does not pop up and my screen turns white. ** ...

Exploring Typescript's Generic Unions

I'm facing an issue where I have an Array of generic objects and want to iterate over them, but TypeScript is not allowing me to do so. Below is a snippet of the code I am working with. Any ideas on how to solve this problem? type someGeneric<T> ...

Is there a way to make a peer dependency optional in a project?

In the process of developing module A, I have implemented a feature where users can choose to inject a Winston logger into my module. As a result, winston becomes a peer dependency. However, when attempting to include module A in another module without th ...

What is the best way to create a generic that can handle readonly types efficiently?

When performing an action on a list type PerformActionOn<L extends any[]> = L The approach I am taking is as follows: const keys = { a: ['a', 'b', 'c'] as ['a', 'b', 'c'], d: ['d ...

Getting access to a variable that was declared in a service class from a component in Angular 9 can be achieved by following

A problem has surfaced in my chat application where the local variable that I set to true in the service class after login is not being accessed correctly from another component. Despite changing it to true, the initial value of false is still being return ...

Refill ag-grid with fresh data

Setting up the ag-grid initialization directly from the HTML using an onGridReady method in the component file. <div style="flex-grow:1;"> <ag-grid-angular style="float:left;width: 100%; height: 201px;margin-top:10px;" class="ag- ...

Tips on creating type definitions for CSS modules in Parcel?

As someone who is brand new to Parcel, I have a question that may seem naive. In my project, I am using typescript, react, less, and parcel. I am encountering an error with typescript stating 'Cannot find module 'xxx' or its corresponding t ...

Is it possible to interchange the positions of two components in a routing system?

driver-details.component.ts @Component({ selector: 'app-driver-details', templateUrl: './driver-details.component.html', styleUrls: ['./driver-details.component.css'] }) export class DriverDetailsComponent implements OnI ...

Ionic 4 does not support the command 'ionic package build ios development'

Struggling to make sense of the ionic 4 documentation, I attempt to build an iOS app on Windows using 'ionic package build ios'. Can this be done? Attempting to create an iOS app with ionic 4 using 'ionic package build ios'. ionic pac ...

Preventing event bubbling/propagation in custom events: a step-by-step guide

Incorporating a module-project from Github into my Angular project, I am able to resize the DOM elements that are displayed on top of a div functioning as a drawing board. To configure my initial rectangles, I am utilizing a combination of mouseDown - mou ...

Error: Unable to convert null or undefined to an object | NextAuth

Recently, I've been attempting to implement a SignIn feature with Nextauth using the following code: import { getProviders, signIn as SignIntoProvider} from "next-auth/react"; function signIn({ providers }) { return ( <> ...

typescript add some flair to the setter function

I'm attempting to enhance a setter function within a class in the following manner: export class SearchResultSortBy{ private sortByChoice; constructor() { ...} /* getters & setters */ get sortBy() { return this.sortByCh ...

What exactly is the purpose of the colon in JavaScript's import statement?

Looking at the following example. import { QueryClientContract, TransactionClientContract } from '@ioc:Adonis/Lucid/Database' I am puzzled by the use of colons and I am unsure about where the imported files are being referenced from. ...

Troubleshoot Angular2 modules efficiently using source mapping features

Is there a way to debug Angular2 module code using TypeScript source mapping in the browser? After installing my project with the "npm install" command following the steps in https://angular.io/guide/quickstart, I noticed that while source mapping is ava ...

In the case that the prop is empty or undefined, display an error message before rendering the full component

I am working on an ImageBlock component, which has several props like url, alt, caption, and optionally quality with a default value of 75. The essential prop here is the url. I need a quick way to immediately display an AlertError if the url is not provi ...