What could be causing the undefined properties of my input variables in Angular?

Currently, I am fetching data from a service within the app component and passing it down to a child component using @Input. Oddly enough, when I log the data in ngOnInit, it appears correctly in the child component. However, when I try to assign it to a variable and utilize it in the child template, it returns as undefined, leaving me puzzled about the cause.

In my app.component.ts file, this is where I invoke my service and encounter issues with the data stored in 'colorCounts'. Inside the ngOnInit function, logging confirms the correct data. The colorCounts object has properties for red, yellow, and green:

ngOnInit() {

    this.pciService.getPciInfo()
            .subscribe((pciInfo) => {
              this.spinner.hide();
              this.pciData = pciInfo.sorted,
              this.colorCounts = pciInfo.counts;
            });

Below is the snippet from app.component.html where the data is passed down:

<app-navbar *ngIf="colorCounts" [colorCounts] = "colorCounts"></app-navbar>
<app-system-status [pciData]="pciData"></app-system-status>

In the child component, while I can successfully capture the data by console.log in ngOnInit, attempting to access "red" in the template or store it in the class results in being undefined:


  constructor(private pciService: PciService,
              public dialog: MatDialog,
              private decimalPipe: DecimalPipe) { }

  AMVersion: any;
  @Input() colorCounts: Colors;


  openDialog(): void {
    let dialogRef = this.dialog.open(AmVersionDialogComponent, {
      panelClass: 'custom-dialog-container',
      data: {}
    });

    (<AmVersionDialogComponent>dialogRef.componentInstance).AMVersion = this.AMVersion;
    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
    });
  }


  ngOnInit() {
    this.pciService.getAMVersion()
    .subscribe((AMInfo) => {
     return this.AMVersion = AMInfo;
    });
    var red = this.colorCounts.red;
    console.log(red)
    console.log(this.colorCounts);
  }

}

It seems like there might be something straightforward that I'm overlooking in terms of the life cycle. Any guidance on how to address this issue would be greatly appreciated.

Answer №1

Every Observable is asynchronous, so when using the template *ngIf, it will check if a variable is null and return null if it is. However, if you use the | async pipe on the variable, it will continuously monitor the variable. Once the variable is not null, the content within the ngIf will be displayed.

*ngIf only runs once! It does not wait for any HTTP calls, while Observables typically involve one. If you want *ngIf to wait for calls, you should utilize the | async pipe.

Similar to subscribing in the ngOnInit() method and assigning values in the template, subscriptions will assign those values later after the template has already been rendered. Make sure to understand the concepts of asynchronicity.

Remember that boilerplate code looks like this:

ngOnInit() {

    this.pciService.getPciInfo()
            .subscribe((pciInfo) => {
              this.spinner.hide();
              this.pciData = pciInfo.sorted,
              this.colorCounts = pciInfo.counts;
            });

A more efficient way to handle this would be:

ngOnInit() {
this.pciInfo$ = this.pciService.getPciInfo()
}

In the template:

<ng-container *ngIf="pciInfo$ | async as pciInfo">
<app-navbar [colorCounts]="picInfo.counts"></app-navbar>
</ng-container>

The Async pipe will automatically subscribe to an Observable for 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

Exploring the intricacies of managing nested data in a Firebase Database (web)

I understand this question may have similarities to others already asked, so my apologies in advance. I am seeking a clear, up-to-date solution that aligns with my expectations. If I have an object labeled "Item One", how can I retrieve the array of "subI ...

What is the process for including a task in the current method?

I've been working on building a web app similar to Google Calendar. I have successfully created the necessary objects and methods, but now I need to implement a feature that allows users to add tasks. My current idea is for users to input a task which ...

Can an enum be declared in Typescript without specifying a type explicitly?

Within an interface, I have a group of 10+ (optional) members, most of which have a specific set of potential values. To streamline this, I would like to utilize enums. However, creating separate enum types for each member (which are only used once and hav ...

Issue with displaying data using a custom pure pipe and boolean in ngIf condition

For my current web project, I require a friendship/follow feature. There are two roles involved: admins and regular users. Regular users have the ability to follow other users, while admins do not possess this capability. When a user wishes to follow anot ...

Inserting an HTML element into Handlebars.js during a specific iteration of an each loop

I have a channel.json file containing 7 objects of data which are iterated in hb. I am looking for a way to insert a date between these iterations without modifying the .json file. How can I add an html tag to display after the 3rd iteration within the loo ...

I encountered an infinite loop issue with Material UI tabs when loading my component within the navigation bar (AppBar > TabPanel)

I am currently working on an application for a school project, and I'm incorporating Material UI into it. Following the official documentation provided on their website. This is the link I have been referring to: Code. My goal is to load a new comp ...

Can object-fit be preserved while applying a CSS transform?

Currently, I am developing a component that involves transitioning an image from a specific starting position and scale to an end position and scale in order to fill the screen. This transition is achieved through a CSS transform animation on translate and ...

Modifying the property value based on the selected item from a dropdown menu in Angular 2

I am brand new to Angular 2 and I have come across the following code snippet. <select name="shape_id" (change)="changeShape()"> <option *ngFor="let shape of shapes" [ngValue]="shape.name"> {{shape.name}} </option> </s ...

Why Isn't the Element Replicating?

I've been working on a simple comment script that allows users to input their name and message, click submit, and have their comment displayed on the page like YouTube. My plan was to use a prebuilt HTML div and clone it for each new comment, adjustin ...

Ensure that a variable adheres to the standards of a proper HTML template

I'm struggling with a problem in my Angular application. I need to ensure that a TypeScript variable is a valid HTML template to compile successfully, like this: let v = '<div>bla…</div>' However, if the variable contains inco ...

Ensuring Proper Typing for Conditional Arrays in Typescript: A Guide

I struggled to find a satisfactory way to define arrays with conditional elements, despite the various methods discussed here. As a result, I decided to simplify the declaration process by creating a helper function. While the helper function itself is str ...

Having trouble receiving JSON/JSONP correctly

I've been exploring the world of APIs and I'm facing a roadblock right at the beginning. My goal is to extract data from the Fever Public API in order to retrieve a list of subscribed RSS feeds. The API appears to be straightforward - check it ou ...

Is the async pipe automatically unsubscribing from an observable that is defined in a service and referenced in a component variable?

Within my service, I have a BehaviourSubject declared and I reference it with a variable in another component. In the view of that component, I subscribe to the subject using the said variable, as shown below: Service: public exampleSubjebt$ = new Behavi ...

What is the best way to specify the data type of a value within a map in TypeScript?

I need assistance defining the value of a key in a map as a key-value pair in TypeScript. map: { key: someStruct } Is it possible to declare the type of someStruct and initialize it simultaneously? What is the best approach for accomplishing this? ...

Encountering TypeError with Next.js and Firebase: Unable to access properties of undefined (specifically 'apps')

My goal is to create an authentication system using NextJS and Firebase. The issue I am facing is in my firebaseClient.js file, where I am encountering the error "TypeError: Cannot read properties of undefined (reading 'apps')". Here is a snipp ...

Modifying the structure of serialized data

After serializing a JS form, the data looks like this: .....&xx=xxx&otherError=&input=SMS&message=sdfgs&...... Can anyone provide guidance on how to replace the value of message with the content of a textarea before making an ajax cal ...

Error message occurs when trying to undo the Union operation in ArcGIS 10.2, resulting in an undefined or null reference error

I am currently working on incorporating a polygon union functionality using ArcGIS 10.2 JavaScript 3.6 API with undo and redo capabilities. The union operation works fine, but I encounter an error when attempting to undo the operation: An unhandled except ...

What is the best way to display these images correctly within a slider?

My goal is to display 4 images/company logos per slide, but they all end up clustered on one slide. Despite my efforts to adjust the CSS, nothing seems to work. This is what my code currently renders: Here are the react component codes I am using: To se ...

Hide button for the last input form to dynamically remove in jQuery

At first, I hide the remove button when there is only one form. However, if there are multiple forms and the user deletes all of them, I want the last form to remain visible and not be deleted. Can someone assist with this issue? Here is my code: <! ...

What steps should I take to successfully install using npm if I keep encountering the same error?

Every time I attempt to install a package using npm, I encounter the following warning: npm WARN EBADENGINE Unsupported engine { npm WARN EBADENGINE package: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c7b3aeaba2b3be ...