Each element in ngFor triggers the invocation of ngAfterContentInit by Angular

In my Angular 11 (Ionic 5) app, I have a scenario with two components: A ContainerComponent and a BoxComponent. Both of these components are completely transparent (

template: '<ng-content></ng-content>'
). The challenge is for the container component to keep track of the number of box components that are placed into it by a third component. However, my solution fails when the third component uses *ngFor directive to insert the boxes into the container (Option B below).

container.component.ts

import { Component, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
import { BoxComponent } from './box.component';


@Component({
  selector: 'container',
  template: '<ng-content></ng-content>',
  styleUrls: ['container.component.scss'],
})
export class ContainerComponent implements AfterContentInit {
  // keeping track of the number of boxes
  private count: number = 0;

  @ContentChildren(BoxComponent)
  private boxes!: QueryList<BoxComponent>;
  
  ngAfterContentInit(): void {
    this.count++;
    console.log(count);  // See result below
  }
}

The third component inserts n BoxComponents into a ContainerComponent.

Option A: n boxes hardcoded into the template of the third component

<container>
    <box>Box 1</box>
    <box>Box 2</box>
    // ...
    <box>Box n</box>
</container>

Option B: n boxes dynamically added into the template of the third component using *ngFor directive

<container *ngFor="let box of boxes">
    <box>{{box.label}}</box>
</container>

Difference between option A and option B

When opting for option A, Angular triggers ngAfterContentInit only once resulting in

count = n

However, with option B, Angular calls ngAfterContentInit n times leading to a constant value of 1 for count.

count = 1, 1, ..., 1    // repeated n times

I find this behavior quite peculiar as it implies that Angular generates a new instance of ContainerComponent for each BoxComponent.

Answer №1

In my opinion, this is the correct functionality. The ngFor directive will loop through the boxes array and generate a new instance of the component for each item.

If you want to achieve a different outcome, consider placing the ngFor directive inside the box component:

<container>
  <box *ngFor="let box of boxes">{{box.label}}</box>
</container>

Best wishes!

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

Issues with Angular RxJS handling Firebase JSON data correctly

Currently developing a CMS app, I am using the login button on Google Firebase to test fetching data. Upon using rxjs to properly return JSON data, I encountered an issue where it returns an odd object with some kind of token attached. Seeking assistance o ...

The selected data was inserted as a foreign key, leading to an Integrity constraint violation with SQLSTATE[23000]: 1048

Hello and thank you for joining us! I am currently working on a task that involves selecting the acc_id from the account_info table and inserting it as a Foreign Key into the patient_info table. Unfortunately, I have encountered an error: While testing ...

Incorrect date being sent by Mat Date picker

I am encountering an issue with date selection using this input field <mat-form-field class="w-full"> <mat-label>{{ "DATE" | translate }}</mat-label> < ...

How can I programmatically trigger the optionSelected event in Angular Material's autocomplete?

I'm currently facing an issue with my Angular Autocomplete component. I am trying to trigger the (optionSelected) event within the ts file after a different event by setting the input with the updated option using this.myControl.setValue(options[1].va ...

Snackbar and RTK Query update trigger the error message: "Warning: Cannot update during an existing state transition."

I've built a basic ToDos application that communicates with a NodeJS backend using RTK Query to fetch data, update state, and store cache. Everything is functioning properly as expected with the communication between the frontend and backend. Recently ...

How can I create and utilize a nested array within an ngFor loop?

*ngFor="let arr = ['foo', 'bar', 'sla']; let item of arr; let i = index;" Why does setting the instantiation of arr before let item of arr; result in an exception displaying [object Object]? Why am I unable to structure it th ...

Windows authentication login only appears in Chrome after opening the developer tools

My current issue involves a React app that needs to authenticate against a windows auth server. To achieve this, I'm hitting an endpoint to fetch user details with the credentials included in the header. As per my understanding, this should trigger th ...

What is the best way to simulate the "window.screen.orientation.lock" function with Jest?

Within our hybrid app, we have implemented a cordova plugin to control screen orientation. The AppComponent contains code that manages the screen orientation locking using the window.screen.orientation.lock function. Is there a way to create a mock versi ...

The name 'CallSite' is missing from the Error stack trace when working with Node.js and TypeScript

I am facing an issue with the following code: Error.prepareStackTrace = function ( error: Error, stack: Array<CallSite>, ) { return self.parse(fiber, error, stack) } I am attempting to import the CallSite, but it seems like it cannot be found ...

Jasmine-core steers clear of incorporating angular-devkit/build-angular into its installation process

Upon running ng serve, an error related to angular-devkit has surfaced. As a result, I proceeded to install it, but encountered the following error: npm install @angular-devkit/build-angular npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to re ...

Troubleshooting problem with Angular2 installation

Can someone please shed light on the current problem I am facing with the updated version of angular-cli? It was running smoothly earlier but now it keeps showing an error message saying "The "@angular/compiler-cli" package was not properly installed." An ...

Solving the issue of "Property does not exist on type 'never'" in @tusharghoshbd/ngx-datatable Advanced Search with Angular

Currently, in my Angular-13 project, I am working on implementing an Advanced Search feature using @tusharghoshbd/ngx-datatable Below is the code snippet: interface: export interface Merchant { id?: number; merchant_name?: string; account_number?: ...

Angular5: Utilizing animations to seamlessly swap out content within a div, smoothly adjust the height of a container, and elegantly fade out the existing content. (See the provided "nearly perfect" Pl

As I work on implementing an animation in Angular 5 to swap the content of a container and adjust the height accordingly, I encounter some challenges. The animation should proceed as follows: 1. Fade out the current content (opacity 1->0) 2. Adjust th ...

Ways to conceal a fabric button

Is there a way to hide my Material button properly? The button appears grey and works fine: <button mat-raised-button class="mat-primary" (click)="deleteClick()" [disabled]="data.createMode"> <mat-icon>delete_forever</mat-icon>DELET ...

The BullMQ library is optimizing performance by efficiently managing Redis connections

Currently, I'm in the process of implementing logic to efficiently reuse redis connections with bullMQ by referring to this specific section in the bullMQ documentation. My setup involves utilizing the latest BullMQ npm version (1.80.6). As per the ...

Combining types: unable to utilize the second optional type within a for loop

I am facing an issue while looping through an array due to the union type. I am wondering what I have overlooked in the code below that is causing Visual Studio Code to not recognize the second optional type for that specific array. class Menu { // name ...

Optimizing Array Comparison in JavaScript and Angular 2

In my Angular 2 .ts (TypeScript) file, I have declared two arrays as shown below: parentArray: Array<Model> initialized with {a, b, c, d} modifiedArray: Array<Model> modified with data {c, e, f, g} How can I efficiently determine the differ ...

The entire React component is not rendering as expected when calling res.render in PugJS within Express

Seeking guidance for the following issue: I have developed a PugJS view that is rendered within an ExpressJS route. In the call to the ExpressJS function res.render, the React component is included as data inside the .render() function call.... The prob ...

Utilizing a dot as the initial character ( .90 ) in conjunction with ngx-mask

Struggling with integrating ngx-mask in my Angular 15 application. Here is how my textbox is set up: <input type="text" [(ngModel)]="sharePrice" mask="separator.4" separatorLimit="9999999999" [dropSpecialCharacte ...

What is the best way to modify just the method signature in typescript?

I'm looking to implement an external array-like interface called ListOf<T>. It has properties like length, indexed access, and a forEach method that takes a callback function. Here's how it looks: interface ListOf<T> { readonly leng ...