Is there a way to make an angular component reuse itself within its own code?

I am dealing with a parent and child component scenario where I need to pass data from the parent component to the child component. The aim is to display parentData.name in the child component when parentData.isFolder===false, and if parentData.isFolder===true, then reusing the child component until there are no more instances of parentData.isFolder===true.

However, my attempts have resulted in an error message:

Error: Maximum call stack size exceeded

Here's a StackBlitz example that I tried.

If this approach is incorrect, is there another way to achieve the desired outcome?

parent-component.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-parent-component',
  templateUrl: './parent-component.component.html',
  styleUrls: ['./parent-component.component.css'],
})
export class ParentComponentComponent implements OnInit {
  public parentData;
  constructor() {}

  ngOnInit() {
    this.parentData = [
      {
        name: 'Example file 1',
        isFolder: true,
        Id: '111',
      },
      {
        name: 'Example file 2',
        isFolder: false,
        Id: '222',
      },
      {
        name: 'Example file 3',
        isFolder: false,
        Id: '333',
      },
    ];
  }
}

parent-component.component.html

<ng-container *ngFor="let item of parentData">
  <app-child-component [parentData]="item"></app-child-component>
</ng-container>

child-component.component.ts

import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-child-component',
  templateUrl: './child-component.component.html',
  styleUrls: ['./child-component.component.css'],
})
export class ChildComponentComponent implements OnInit {
  @Input() public parentData;

  constructor() {}

  ngOnInit() {}

}

child-component.component.html

<!-- Display names when isFolder === false -->

<ng-container *ngIf="parentData.isFolder === false">
  <ul>
    <li>{{ parentData.name }}</li>
  </ul>
</ng-container>

<!-- Reuse the app-child-component if isFolder === true -->
<ng-container *ngIf="parentData.isFolder === true">
  <app-child-component [parentData]="parentData"> </app-child-component>
</ng-container>

Answer №1

The reason you encountered the error "Error: Maximum call stack size exceeded" is due to not handling the parentData properly when it evaluates as true, causing an infinite recursion.

It seems like you are attempting to create a tree structure.

To address this issue, I made some modifications to your code:

  • parent.component.html - Modified the HTML to pass an array instead of just an object to the child component.
  • parent.component.ts - Added a subFolders array within the parentData to simulate subfolders for the tree UI. You can rename subFolders to parentData for clarity.
  • child.component.html - Restructured the HTML by iterating over the parentData array received from the parent component to display folder names. The child component calls itself recursively until isFolder property is false.
  • child.component.ts - No changes made here.

I also created a modified version on StackBlitz based on your initial project.

parent.component.ts

// Code for Parent Component
// Initialization and assignment of data

parent.component.html

<app-child-component [parentData]="parentData"></app-child-component>

child.component.ts

// Code for Child Component
// Input declaration and initialization

child.component.html

<ng-container *ngFor="let item of parentData">
  <ul>
    <li>{{ item.name }}</li>
    <app-child-component [parentData]="item.subFolders" *ngIf="item.subFolders"></app-child-component>
  </ul>
</ng-container>

Outcome:

https://i.stack.imgur.com/DwXSp.png

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

Issue TS2315: Type 'ElementRef' does not support generics

While attempting to integrate @angular/materials into my application, I encountered a successful compilation with the following error messages: webpack: Compiled successfully. ERROR in node_modules/@angular/material/button-toggle/typings/button-toggle.d.t ...

Stop the pinch zoom functionality in Angular NativeScript WebView to prevent unwanted zooming

Currently, I am working on a Nativescript App that utilizes Angular (NG 5.1.1 / Angular 7.x). Within the app, there is a view containing a webview. @ViewChild("myWebView") webViewRef: ElementRef; <WebView class="webview" #myWebView [src]="myU ...

Unit Testing Angular: Mastering Unit Testing for the .map() Function

I am in need of testing a service method, but I am unsure about how to achieve complete coverage for the code that gets executed as a result of calling another injected service method. The Service Method to be tested: @Injectable() export class BomRevisi ...

Encountering a 401 Error while integrating Azure App Configuration within an Angular 9 Application

After implementing the library found at https://www.npmjs.com/package/@azure/app-configuration Despite following the setup instructions, I encounter a 401 error whenever I make a request using the AppConfigurationClient. The response headers indicate: ww ...

Stripe-node does not return metadata when accessing a Checkout Session's line items

I have successfully set up a stripe checkout session where I am passing the products from the request's body in the line_items property. Each product in the product_data includes metadata with the product's id. try { const cart: ICart[] = ...

When utilizing Rx.Observable with the pausable feature, the subscribe function is not executed

Note: In my current project, I am utilizing TypeScript along with RxJS version 2.5.3. My objective is to track idle click times on a screen for a duration of 5 seconds. var noClickStream = Rx.Observable.fromEvent<MouseEvent>($window.document, &apos ...

What is the reason behind starting certain scripts using "npm start x" while others only require "npm x"?

Within the package.json file, I have included a section dedicated to defining scripts for various tasks: "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build --prod", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, ... When lau ...

Encountering a problem with the mock object in Angular 11 unit testing when converting a JSON object to a TypeScript interface

Within my Angular 11 application, I am working with a JSON response and have defined an interface to match the structure of this JSON object. The JSON object looks like this: { "division": { "uid": "f5a10d90-60d6-4937-b917- ...

Error: The token 'export' in d3zoom is causing a syntax issue

I'm encountering issues with executing tests in Angular: ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export {default as zoom} from "./zoom.js"; ...

What is the best way to display multiple HTML files using React?

Looking to develop a web application using React that consists of multiple HTML pages. For instance, login.html and index.html have been created and linked to URIs through the backend - resulting in localhost:8080/login and localhost:8080/index. However, R ...

Unable to utilize the "let" keyword in WebStorm

Currently, I am delving into learning typescript and attempting to create a simple 'let' statement. However, I encountered an error indicating the need to use ECMAScript 6 or later versions. The exact message from the typescript compiler states: ...

Typescript validation for redundant property checks

Why am I encountering an error under the 'name' interface with an excess property when using an object literal? There is no error in the case of a class, why is this happening? export interface Analyzer { run(matches: MatchData[]): string; } ...

Slim and Angular2 htaccess configuration

I am encountering an issue with my htaccess file and could use some assistance. My setup includes an Angular2 app (single page client side app, index.html) and a slim-v3 PHP REST API (index.php). The Angular2 app interacts with the REST API, and I would id ...

Where specifically in the code should I be looking for instances of undefined values?

One method in the codebase product$!: Observable<Product>; getProduct(): void { this.product$ = this.route.params .pipe( switchMap( params => { return this.productServ.getById(params['id']) })) } returns an ...

Handling JSON data with Reactive Extensions in JavaScript

Hey everyone, I'm a beginner in Angular and RxJS coming from a background in VueJS. I've been struggling to grasp the inner workings of RxJS and would really benefit from some guidance from more experienced individuals regarding my current issue. ...

Error message in Angular 8: Cannot be assigned to AsyncValidatorFn

I am currently working on implementing a custom validator function in a reactive form. Here is the code snippet: form.component.ts ... form = new FormGroup({ username: new FormControl('', [ Validators.required, ...

How to Generate a Unique URL in Angular 7 Using Typescript

I'm struggling to display or download a .pdf file in my Angular 7 project due to issues with window.URL.createObjectURL. Here's the code snippet I've written: this.userService.getFile(report.id).subscribe( res => { console.log(res) ...

Having trouble getting Jest to manually mock in Nestjs?

When setting up a mock service like this: // /catalogue/__mock__/catalogue.service.ts export const CatalogueService = jest.fn().mockImplementation(() => { return { filterRulesFor: jest.fn().mockImplementation((role: Roles): Rule[] => rules.filt ...

Steps for importing the config ts file into another ts file in Ionic 2

When trying to import the app.config.ts file in another ts file such as /pages/home/home.ts, I have included the following code in app.config: import { OpaqueToken } from "@angular/core"; export let APP_CONFIG = new OpaqueToken("app.config"); e ...

Deliver router services for central Angular 2 elements

I am working on an ng2 app where I have the app/app.module and core/core.module. In the core modules, there are some modules that are used at the app top level and only once as mentioned in the official documentation. However, one of these modules requires ...