Is there a way to prevent Angular component lifecycle hooks like ngOnInit/ngOnDestroy from being triggered when nested within one another?

I am currently developing an application with a page structure that resembles the following:

Displaying Objects retrieved from Firestore (similar to Instagram posts)

  • Loading Comments (using the object's id to display comments sub-collection)
    • Loading Replies (using the object and comment id to display replies sub-collection)

Here is a simplified version of the code:

<div class="container">
  {{ object.data.text }}
  {{ object.data.likes.length }}
  <comment objectid="{{object.id}}">
</div>

Comment selector

A simplified version of the comment template:

<div *ngFor="let comment of comments | async" class="container">
  {{ comment.data.text }}
  {{ comment.data.likes.length }}
  <reply commentid="{{comment.id}}">
</div>

Replies selector

A simplified version of the reply template:

<div *ngFor="let reply of replies | async" class="container">
  {{ comment.data.text }}
</div>

Issue: When the number of likes in comment.data.length changes for the object, the reply selector goes through the full ngOnInit and ngOnDestroy lifecycle. However, when the number of likes in object.data.length changes, there is no lifecycle trigger for the comment or reply selector. This results in the replies being refreshed every time a user likes a comment, which is not ideal.

Has anyone encountered this issue before or knows how to resolve it?

Answer №1

The challenge arises when the array inside the *ngFor undergoes a change in reference. Angular then re-renders all the items because it cannot determine which specific item has changed. Consequently, it removes everything and reinserts all the items again.

To address this issue, it is essential to incorporate the trackBy function. This function informs Angular on how to compare the objects within the loop and detect any changes they might have undergone. By doing so, Angular can efficiently replace only the items that have changed rather than refreshing all items.

Thus, instead of

*ngFor="let comment of comments | async"
,

you should use:

*ngFor="let comment of comments | async; trackBy: myTrackByFn"

Here, myTrackByFn is a function that needs to be implemented in the corresponding .ts file:

myTrackByFn(index, item) {
    return item.id; // include a unique key for the iterated item
}

It's important to apply this function to all three instances of *ngFor in your code.

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

Strategies for integrating user data into Vue components within Laravel

I've successfully logged my user data in the console, but when I try to display the data on Contalist page, nothing is returned. I'm new to using Vue and need help implementing it into my projects. Below are my PHP controller and Vue component fi ...

Mapping an array in ReactJS based on the specific order of another array

In my experience with Unmitigated, the answer proved beneficial. If you're arriving from a Google search, please scroll down for more information. Order: [ "567", "645", "852", "645", "852", "852 ...

Create a unique shader in Three.js that remains unaffected by the fog effect

I have implemented a custom shader to add glow to a sphere on my scene. However, I noticed that the fog in the scene affects the sphere but not the glow. When I zoom out, the sphere disappears but the glow remains visible. Is there a way to make the fog ...

What is the most effective way to add images to a table using JavaScript?

Is there a way to insert images into the "choicesDiv" without having to make changes to the HTML & CSS? Here is the table code: <table id="choices"> <tr> <td><div class="choicesDiv" value="1"></div></td> ...

Validation of Arrays in Angular Schema Form

Trying to create an array of distinct values through Schema Form appears to be a challenging task. To simplify, let's examine this basic unique validator: $scope.validateUnique = function(value) { console.log('running validation'); ...

Is there a way to set the size of my unique carousel design?

Having some trouble with my modal image carousel; the dimensions keep shifting for different image sizes. Image 1 Image 2 ...

Received the error message "Material-UI: capitalize(string) expects a string argument" while implementing the snackbar feature in a React Material-UI project

While working with Material-UI, I came across an issue with the snackbar where I received an error message saying: Error: Material-UI: capitalize(string) expects a string argument. Here's a snippet of my code: this.state = { snackBarOpenVer ...

A guide on manipulating an input field to trigger md-datepicker upon clicking

What is the best way to convert an input text into a fire md-datepicker and achieve a similar result like this? ...

Combining jQuery form validation with a PHP script on a single webpage

After implementing jQuery form validation and redirecting using the function btn_onclick() { window.location.href = "http://localhost/loginprivate.php";} from index.php to loginprivate.php, my web app's PHP script is not being executed. The user is re ...

What is the best way to send multiple parameters to @Directives or @Components in Angular using TypeScript?

I am facing some confusion after creating @Directive as SelectableDirective. Specifically, I am unclear on how to pass multiple values to the custom directive. Despite my extensive search efforts, I have been unable to find a suitable solution using Angula ...

Resetting dynamic form changes in Vue.js explained

Currently, I am using a template like this: <div> <div v-for="(item, key) in items" :key="key"> <div> <input type="text" :value="item.title"> </div> ...

What is the correct placement for the "require("firebase/firestore");" code in my Angular 4 project?

After doing thorough research on the internet and carefully reading through the Firestore documentation, I am facing difficulties in converting my partially built Angular (4) project. Following the instructions in the "Get Started with Cloud Firestore" gu ...

Iterating through an array and setting variables according to asynchronous code

I have created a function to loop through an array, call a promise, and update a variable based on the result. The code seems to be functioning correctly, but I am wondering if there is a more optimal way to write it. Any suggestions are appreciated. Tha ...

Neglecting to automatically align text

My goal is to automatically align text based on the language, so that Arabic text starts from the right and English text starts from the left. After some online research, I discovered that I need to use dir="auto" in the tag and text-align: auto; in the CS ...

Elevating font-awesome from version 4.7 to 5.11.1 in an Angular 6 project

Currently in my angular 6 project, the parent module utilizes font-awesome 4.7 as shown in package.json; "font-awesome": "^4.7.0", and angular.json; "styles": ["projects/adminUI/src/styles.css", "./no ...

What could be causing my webpage to freeze every time a filter button is selected?

Tasked with developing a webpage similar to Pinterest by utilizing data from a JSON response. Each JSON object contains a service_name key, which can be manual, twitter, or instagram. I made an effort to implement three filter buttons to only display the r ...

"Delving into the intricacies of Angular's factory

If I have a factory like the one below: app.factory("categoryFactory", function (api, $http, $q) { var selected = null; var categoryList = []; return { getList: function () { var d = $q.defer(); if(categoryL ...

Guide to creating nested collapsing rows in AngularJS

My attempt to implement expand and collapse functionality in AngularJS for a section is not yielding the desired result. To demonstrate, I created a simple demo of collapsible/expandable sections in AngularJS which works fine. You can view it here. The ex ...

Employing async await for postponing the execution of a code block

I have been working on an Angular component where I need to perform some actions after a data service method returns some data asynchronously. Although I attempted to use async/await in my code, I feel that I may not have fully understood how it works. Her ...

How can you create a scenario in Angular Material where items in a toolbar transition to the second line exclusively on mobile screens?

Visit the Angular Material website to see how the toolbar appears on a desktop: https://material.angular.io/ https://i.sstatic.net/KPFMv.png On mobile devices, the menu items Components, CDK, and Guides are displayed on the second line, while github, the ...