Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 7 error RangeError: Maximum call stack size exceeded

I am trying to learn angular by following the official tutorial but when following steps for hero component and hero detail component, it raises an error "RangeError: Maximum call stack size exceeded".

The hero.component.html:

<ul class="heroes">
  <li *ngFor="let hero of heroes" (click)="onSelect(hero)" [class.selected]="hero === selectedHero">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

<!-- 
<app-hero-detail [hero]="selectedHero"></app-hero-detail> -->


<app-heroes></app-heroes>

The detail component:

<div *ngIf="hero">

  <h2>{{hero.name}} Details</h2>
  <div><span>id: </span>{{hero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="hero.name" placeholder="name"/>
    </label>
  </div>

</div>

<app-hero-detail [hero]="selectedHero"></app-hero-detail>

The hero component

import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';
import { HEROES } from '../mock-heroes';
import { HeroService } from '../hero.service';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
  heroes: Hero[];

  selectedHero: Hero;

  constructor(private heroService: HeroService) { }

  ngOnInit() {
    this.getHeroes();
  }

  getHeroes(): void {
    this.heroes = this.heroService.getHeroes();
  }

  onSelect(hero: Hero): void {
    this.selectedHero = hero;
  }

}

The hero.detail component

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

@Component({
  selector: 'app-hero-detail',
  templateUrl: './hero-detail.component.html',
  styleUrls: ['./hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {

  @Input() hero: Hero;
  constructor() { }

  ngOnInit() {
  }

}

one thing to mention is that when <app-heroes></app-heroes> is commented, the list page is loaded without an error

Error message screenshot any help is appreciated

like image 356
Abdul Ali Avatar asked Dec 13 '18 06:12

Abdul Ali


People also ask

How do I fix error RangeError Maximum call stack size exceeded?

The call stack is limited in size, and when it's exceeded, the RangeError is thrown. This can happen when a deeply nested function is called, or when a lot of new variables are created. The most common way to fix this error is to reduce the number of function calls, or to limit the number of variables that are created.

What is maximum call stack size exceeded?

The JavaScript exception "too much recursion" or "Maximum call stack size exceeded" occurs when there are too many function calls, or a function is missing a base case.


7 Answers

1.This error occur when there is an infinite loop. As you have mentioned that the page loads when app-heroes is commented, this might be used as selector-name for more than one component which is not allowed. This can cause an infinite loop and fail to load components.

  1. Try making below edits,

hero.component.html

<ul class="heroes">
  <li *ngFor="let hero of heroes" (click)="onSelect(hero)" [class.selected]="hero === selectedHero">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

<app-hero-detail [hero]="selectedhero"></app-hero-detail> 

hero.detail.component.html

<div *ngIf="hero">
  <h2>{{hero.name}} Details</h2>
  <div><span>id: </span>{{hero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="hero.name" placeholder="name"/>
    </label>
  </div>
</div>

Hope this helps.

like image 66
Santhosh mp Avatar answered Oct 18 '22 03:10

Santhosh mp


In your example you render component inside yourself, so you never finish this operation and all time render another child component (if second part of block is

Update - more details:

If you write app with components, all components are hierarchical, so you can include the same component inside yourself only if you are sure, that this is limited amount of loop inside. In your code example you has unlimited nested components, because child component generate next child component inside yourself body. In result your browser display error: RangeError: Maximum call stack size exceeded

hero.component.html

<ul class="heroes">
  <li *ngFor="let hero of heroes" (click)="onSelect(hero)" [class.selected]="hero === selectedHero">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

<!-- 
<app-hero-detail [hero]="selectedHero"></app-hero-detail> -->


<app-heroes></app-heroes>

app-hero-details.component.html

<div *ngIf="hero">

  <h2>{{hero.name}} Details</h2>
  <div><span>id: </span>{{hero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="hero.name" placeholder="name"/>
    </label>
  </div>

</div>

// you should comment line below
// <app-hero-detail [hero]="selectedHero"></app-hero-detail>
like image 32
kris_IV Avatar answered Oct 18 '22 03:10

kris_IV


I will add an answer that describes a different cause for this error when upgrading to angular 8 an existing application and using new routing features.

In my case, I added to each lazy loaded route the data object with preload set to true || false using the new syntax:

  {
    path: '',
    loadChildren: () => import('./views/home/home.module').then(mod => mod.HomeModule),
    data: { preload: true }
  },

However it took me a while to realize that I had left the preloadingStrategy set to PreloadAllModules in my RouterModule forRoot declaration:

@NgModule({
  imports: [RouterModule.forRoot(
    routes,
    {
      preloadingStrategy: PreloadAllModules, <-- This is the cause
    })],
    ...

Removing preloadingStrategy from the module forRoot declaration and relying on the route data preload definitio fixes the issue.

like image 6
Lucas Avatar answered Oct 18 '22 01:10

Lucas


You have the <app-hero-detail> displayed inside the details HTML.

<app-hero-detail [hero]="selectedHero"></app-hero-detail>

Please try removing this. A similar line is commented in the hero.component.html, you can uncomment that.

like image 4
Sachin Gupta Avatar answered Oct 18 '22 02:10

Sachin Gupta


I was dealing with this error when my intellisense accidentally added the module name (instead of a specific component name) to the exports for the module:

@NgModule({
  declarations: [
    FooComponent,
    // ...
  ],
  imports: [CommonModule],
  exports: [
    FooModule, // <== should be 'FooComponent'
    // ...
  ], 
})
export class FooModule {}

It definitely would be nice if the error was a little more descriptive though, as this tool me some time

like image 4
Kurtis Jungersen Avatar answered Oct 18 '22 02:10

Kurtis Jungersen


This error occurred when I used a circular module import mistakenly on Angular 9.

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
@NgModule({
 imports: [
    CommonModule,
    ModuleTwo
  ],
 
})
export class ModuleOne {
}

and

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
    @NgModule({
    imports: [
        CommonModule,
        ModuleOne
      ],
     
    })
    export class ModuleTwo {
    }
like image 4
Eyayu Tefera Avatar answered Oct 18 '22 03:10

Eyayu Tefera


A different cause for this error when upgrading to angular 8 an existing application and using new routing features in separate file.

In my case not importing the featureRouterModule to its particular featureModule.ts cause maximum stack exceed error.Since angular can't find its particular router file registered

like image 2
Nambi N Rajan Avatar answered Oct 18 '22 03:10

Nambi N Rajan