The rendering of the list is taking an unexpectedly long time due to random factors

I have encountered a strange issue with one of my components. The component fetches a list of objects from a service in the ngOInit(). The problem I am facing seems to occur randomly, where sometimes it takes a considerable amount of time to display this list while other times it appears instantly. Despite ruling out any backend issues as the calls to the backend are consistently fast, I have observed something interesting. By implementing the DoCheck hook, I have noticed that there is a delay between the completion of ngOnInit() and the invocation of ngDoCheck().

Based on Angular's documentation, ngDoCheck() is supposed to be called after ngOnIni(), so it is puzzling why there might be a delay at times. To investigate further, I have added console.log statements to determine the execution time for each call—starting from the end of ngOnInit() when the object list is retrieved, up to the point of ngDoCheck().

The browser console output during the delayed rendering looks like this:

https://i.sstatic.net/6zVQS.png

Upon inspection, it shows that after the completion of ngOnInit(), followed by ngDoCheck(), the object retrieval takes place, and then unexpectedly, 10 seconds later, another ngDoCheck() triggers the actual rendering of the list on the screen.

This snippet showcases part of the component code containing ngOnInit() and ngDoCheck():

  ngDoCheck(){
    console.log('ngDoCheck. N. Items ' + this.items.length, new Date());
  }

  ngOnInit() {
    this.isLoading = true;
    this.sensorTypeConfigEndpoint.getInheritedType().then(result => {
      this.typeInherited = result;
      if (this._markers) {
        const groups = this._markers.map(marker => marker.get('group'));
        if (groups && groups.length) {
          this.getItemsByMapVisualization(this.typeViewMap, _.cloneDeep(groups)).then( items => {
            this.items = items;
            console.log('items N. Items ' + this.items.length, new Date())
            this.isLoading = false;
          });
        }
      }
    });
    console.log('ngOnInit N. Items ' + this.items.length, new Date())
  }

Furthermore, this excerpt displays the HTML structure:

<div class="flex-cards" [ngStyle]="{'max-height': maxHeight}" [class.columnWrap]="isClusterInside" [appLoading]="isLoading">
  <div (click)="expand()" *ngIf="isClusterInside" class="grid-expand">
    <img class="filter-grey" src="assets/images/expand_cluster.svg" alt="Expand" style="width: 100%; height: 100%;margin-left: 4px">
    <p class="text-expand" style="margin-bottom: 10px">
      Expandir
    </p>
  </div>
  <section class="card" style="height: calc(100% - 12px); overflow-y: auto;">
    <div class="content-card">
      <div *ngFor="let item of items">
        {{item.text}}
      </div>
    </div>
  </section>
</div>

If you have any insights into why this delayed rendering of the list occurs sporadically, please share your thoughts.

Answer №1

sensorTypeConfigEndpoint appears to be operating outside of Angular's usual realm. This results in Angular not recognizing changes made to this.items and this.isLoading, causing the view not to update.

It's as if Angular is in a deep slumber, oblivious to any modifications. Using ngDoCheck() acts as a wake-up call for Angular, prompting it to acknowledge the changes and refresh the view. However, this method is more of a workaround than a permanent solution, merely triggering a redraw artificially.

To effectively update the view, utilize ngZone:

import { Injectable, NgZone } from '@angular/core';

...

constructor(public zone: NgZone) { ... }
...

this.items = items;
this.isLoading = false;
this.zone.run(() => { // The magic line
    console.log('items N. Items ' + this.items.length, new Date())
});

Answer №2

Keep in mind that the ngDoCheck function runs during change detection cycles that can impact the component. It will run once after ngOnInit, but may be triggered again by external events like mouse movement, hovering over elements, or clicking - without a specific source tied to your async call. If change detection is not initiated, the DOM will not update, resulting in components not being displayed. It's also important to consider the change detection strategy being utilized and any properties affecting the layout of the component within the template.

To troubleshoot, consider using ChangeDetectorRef to manually trigger a check for changes after the isLoading = false phase in your code. This can help pinpoint if the issue lies in change detection or elsewhere. If this resolves the problem, delve into resources on change detection and angular lifecycle from the official documentation to understand how to address it further - they provide comprehensive insights on these topics.

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

Determine the type of function arguments based on provided hints in TypeScript

It's common to encounter situations like this where TypeScript struggles to infer types due to lack of context. Is there a way to explicitly declare the type of function for the compiler? router.get('/get', imget); router.get('/send&a ...

Steps for making an Angular 6 POST request using OAuth2 authentication and setting the appropriate headers

I am struggling to correctly format a post request to a Spring Boot OAuth 2 Authorization Server in order to obtain the JWT token. Postman returns the token successfully and the Authorization Server is functioning properly. However, when trying to make the ...

How come once I close a PrimeNG modal that is defined within a child component, I am unable to reopen it?

Currently, I am developing an Angular application that utilizes PrimeNG. In the process, I encountered a challenge. Initially, I had a component with a PrimeNG Dialog embedded within (refer to this link), and it was functioning properly. To streamline my ...

Issue with onClick event not functioning properly in a React / Next.js component that is nested

I'm struggling to make the hideMoreDetails() function work on this component. Whenever I click on the 'close-more-info-cross' div, nothing gets logged in the console and the state remains unchanged. Any thoughts? Could it possibly be a stac ...

JavaScript encountered an issue when trying to display HTML content

Through my PHP code, I am attempting to create a popup window that displays the content of an HTML file. However, after adding script tags, no HTML content is displayed. When I tried echoing out $row2, only the word 'array' appeared on the screen ...

Deletion of a custom function in JavaScript

I have written some basic code to generate and remove an image using functions. Specifically, I need help with removing the image created by the function Generate() when a button linked to the function Reset1() is clicked. Here's the code snippet for ...

When functions are sent to children of a react component, they do not inherit the context of the parent

I'm facing an issue while working with React where I am encountering difficulty passing a function from a parent component to multiple children components. The function calls other functions that are also housed within the parent component. Although ...

Angular - Loading images on the fly

After scouring numerous resources, I couldn't find a resolution to my issue. For your information, I am utilizing ASP.net Core 2.0's default angular project In the process of developing an Angular application, I am faced with the challenge of ...

Multiplication table creation in Angular with ngFor

I am attempting to generate a table based on the input value. However, when I display the result, only the last value is shown instead of the entire result due to it being within a for loop. Below is the code from my multiplytable.component.ts file: expor ...

How to retrieve the values of a property from a JavaScript object

Looking for a fresh perspective on this issue. I'm currently retrieving historical data from the cryptocompare API, but I'm having trouble accessing the received values. https://i.sstatic.net/oH6hz.png When I hardcode it as res.data.OMG.USD, I ...

Utilize Dojo to programmatically showcase an image

I'm facing an issue while trying to programmatically display an image using dojo. I have tried using both "dijit/Dialog" and "dojox/image/Lightbox". However, when using the Dialog method, instead of displaying the image, some random characters are sh ...

Iterating through each data attribute using a jQuery each loop

I've encountered an issue with resetting data attributes post-animation and have been attempting to implement a method found on answer 2 of a related thread. I'm a bit stuck on what might be causing the problem. It should theoretically be possib ...

The find functionality in Angular and Firebase seems to be malfunctioning

enter image description here Whenever I try to find the ID and data set is not set on these fields, I encounter an error in my console. The following code snippet displays the find expense code: import { Component } from '@angular/core'; import ...

Is there a way to address the sporadic behavior of rxjs combineLatest when used in conjunction with ReplaySubject

My current struggle lies within this particular example: const r1 = new ReplaySubject(2); const r2 = new ReplaySubject(2); r1.next('r1.1'); r1.next('r1.2'); r2.next('r2.1'); combineLatest([r1, r2]).subscribe(console.log); // ...

Transforming two child arrays within an object into a single array using Ramda

I am looking to transform an object into an array. The object I have is structured like this: const data = { t1: [ {"a": 1, "a1": 2}, {"b": 3, "b1": 4}, {"c": 5, "c1": 6} ], t2: [ {" ...

Incorporate an Array of Objects into the UseState hook with an initial value

I have encountered an issue with the following error message: "Error: Objects are not valid as a React child (found: object with keys {fzfvhv76576, user }). If you meant to render a collection of children, use an array instead." I have been attem ...

Sending a JSON payload from Angular to C# can result in a value of 0 or null being received

As a beginner working on my Angular&C# project, I encountered an issue. Despite sending a JSON from Angular to C# (POST) with values, the C# side is not receiving anything (value 0 for int and null for string). I can't figure out what I'm doi ...

Error retrieving resource: server returned a 404 status code indicating file not found for javaScript and CSS files

I can't seem to get my css and js files to load on the server. Here is how my file structure looks like: GAME_Folder https://i.sstatic.net/wzfB3.png HTML doctype html head link(href='https://fonts.googleapis.com/css2?family=Press+Start+2P& ...

Is your prop callback failing to return a value?

I am currently utilizing a Material UI Table component in my ReactJS project and I would like to update a state variable whenever a row is selected or deselected. The Table component has an onRowSelection prop that gets triggered each time a row is is sele ...

Why does this straightforward CORS request require a pre-flight options verification?

I've encountered an issue with a CORS request to a cross-origin resource. My assumption was that since it's a POST request with a parameter, it would qualify as a simple CORS request and not require a pre-flight call. However, that doesn't s ...