Angular 4 to 18 Migration - Bootstrap error: RangeError: Maximum call stack size exceeded

Discussão em 'Angular' iniciado por Gibosky, Novembro 2, 2024.

  1. Gibosky

    Gibosky Guest

    Issue


    I'm updating an application from Angular 4 to Angular 18 with Django as the backend. When i build the application it gives a infinity loop with the app.component.ts. Added some debuggers and it run the constructor on a loop. But it only happens when i add the . If i add the content of the index without it the loop doesn't happen.

    When looping the developers tools is blank and no console show.

    Errors


    Bootstrap error: RangeError: Maximum call stack size exceeded

    Exception: error : Maximum call stack size exceeded

    RangeError: Maximum call stack size exceeded

    App Flow

    Environment

    • Angular CLI: 18.2.4
    • Node: 18.20.4
    • npm: 10.7.0
    • OS: Linux x64
    Configuration


    Here's my angular.json file:


    {
    "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
    "version": 1,
    "newProjectRoot": "projects",
    "projects": {
    "static": {
    "projectType": "application",
    "schematics": {},
    "root": "",
    "sourceRoot": "src",
    "prefix": "app",
    "architect": {
    "build": {
    "builder": "@angular-devkit/build-angular:browser-esbuild",
    "options": {
    "allowedCommonJsDependencies": ["handsontable"],
    "outputPath": "src/dist/dev",
    "index": "src/index.html",
    "main": "src/main.ts",
    "polyfills": [
    "zone.js",
    "@angular/localize/init"
    ],
    "tsConfig": "tsconfig.app.json",
    "assets": [
    {
    "glob": "**/*",
    "input": "public",
    "output": "/assets"
    }
    ],
    "styles": [
    "src/app/shared/styles.css",
    "handsontable/custom_handsontable.css",
    "node_modules/bootstrap/dist/css/bootstrap.min.css",
    "node_modules/font-awesome/css/font-awesome.min.css",
    "node_modules/handsontable/dist/handsontable.full.min.css"

    ],
    "scripts": [
    "node_modules/jquery/dist/jquery.min.js",
    "node_modules/bootstrap/dist/js/bootstrap.min.js"
    ]
    },
    "configurations": {
    "production": {
    "budgets": [
    {
    "type": "initial",
    "maximumWarning": "3mb",
    "maximumError": "3mb"
    },
    {
    "type": "anyComponentStyle",
    "maximumWarning": "2kb",
    "maximumError": "4kb"
    }
    ],
    "outputHashing": "none",
    "fileReplacements": [
    {
    "replace": "src/environments/environment.ts",
    "with": "src/environments/environment.prod.ts"
    }
    ]
    },
    "development": {
    "buildOptimizer": false,
    "optimization": false,
    "vendorChunk": true,
    "extractLicenses": false,
    "sourceMap": true,
    "namedChunks": true
    }
    },
    "defaultConfiguration": "production"
    },
    "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "configurations": {
    "production": {
    "buildTarget": "static:build:production"
    },
    "development": {
    "buildTarget": "static:build:development"
    }
    },
    "defaultConfiguration": "development"
    },
    "extract-i18n": {
    "builder": "@angular-devkit/build-angular:extract-i18n",
    "options": {
    "buildTarget": "static:build"
    }
    },
    "test": {
    "builder": "@angular-devkit/build-angular:karma",
    "options": {
    "polyfills": [
    "zone.js",
    "zone.js/testing",
    "@angular/localize/init"
    ],
    "tsConfig": "tsconfig.spec.json",
    "assets": [
    {
    "glob": "**/*",
    "input": "public",
    "output": "/assets"
    }
    ],
    "styles": [
    "src/app/shared/styles.css",
    "handsontable/custom_handsontable.css",
    "node_modules/bootstrap/dist/css/bootstrap.min.css",
    "node_modules/font-awesome/css/font-awesome.min.css",
    "node_modules/handsontable/dist/handsontable.full.min.css"
    ],
    "scripts": [
    "node_modules/jquery/dist/jquery.min.js",
    "node_modules/bootstrap/dist/js/bootstrap.min.js"
    ]
    }
    }
    }
    }
    }
    }

    Code


    app.module.ts


    import { ErrorHandler, NgModule } from '@angular/core';
    import { RouterModule } from '@angular/router';
    import { BrowserModule } from '@angular/platform-browser';
    import { HttpClientModule } from '@angular/common/http';
    import { FormsModule } from '@angular/forms';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import { ToastrModule } from 'ngx-toastr';
    import { AppComponent } from './app.component';
    import { AppRoutingModule } from './app.routing';
    import { GlobalErrorHandlerService } from './shared/global-error-handler-service';
    import { SharedModule } from './shared/shared.module';
    import { ProgramsModule } from './programs/programs.module';
    import { TeamsModule } from './teams/teams.module';
    import { AllocationsModule } from './allocations/allocations.module';
    import { ExportModule } from './export/export.module';
    import { ValidationModule } from './validation/validation.module';
    import { ProjectsService } from 'src/services';


    @NgModule({
    imports: [
    BrowserModule,
    HttpClientModule,
    FormsModule,
    BrowserAnimationsModule, // Required for animations
    ToastrModule.forRoot({
    timeOut: 3000,
    positionClass: 'toast-top-right',
    preventDuplicates: true,
    }), // ToastrModule added
    ProgramsModule,
    TeamsModule,
    AllocationsModule,
    ValidationModule,
    ExportModule,
    SharedModule,
    RouterModule,
    AppRoutingModule,
    ],
    providers: [{ provide: ErrorHandler, useClass: GlobalErrorHandlerService }, ProjectsService],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    })
    export class AppModule {
    constructor() {
    console.log('AppModule loaded');
    debugger;
    }
    }




    app.component.ts

    import { filter } from 'rxjs/operators';
    import '../utils';
    import { ChangeDetectionStrategy, Component } from '@angular/core';

    import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';

    import {
    ResourcesService,
    TeamsService,
    AllocationsService,
    ScrumTeamService,
    ProjectsService,
    BusinessUnitService,
    BusinessLineService,
    BusinessCategoryService,
    GlobalListenersService,
    ProductClassesService,
    ExportService,
    SessionService,
    ADUserQueryService,
    HeaderService,
    ResourceFunctionsService,
    ResourceCostCentersService,
    InitiativesService,
    } from '../services';

    @Component({
    selector: 'app-root',
    templateUrl: '../index.html',
    providers: [
    GlobalListenersService,
    ResourcesService,
    TeamsService,
    AllocationsService,
    ScrumTeamService,
    BusinessUnitService,
    BusinessLineService,
    BusinessCategoryService,
    ProjectsService,
    ProductClassesService,
    InitiativesService,
    HeaderService,
    ExportService,
    SessionService,
    ADUserQueryService,
    ResourceFunctionsService,
    ResourceCostCentersService,
    ],
    })
    export class AppComponent {
    protected activeRouteTitle!: string;
    protected menuToggle = false;
    protected supported = true;
    private initCount = 0;

    constructor(private route: ActivatedRoute, private router: Router) {
    console.log("App Component Constructor");
    this.router.events
    .pipe(filter((event) => event instanceof NavigationEnd))
    .subscribe(() => {
    console.log('Navigation Start');
    debugger;
    let currentRoute = this.route.root;
    console.log('Current Route', currentRoute);
    while (
    currentRoute.children[0] !== undefined &&
    currentRoute.snapshot.data['title'] == undefined
    ) {
    console.log('Navigation While Loop');
    currentRoute = currentRoute.children[0];
    break;
    }
    console.log('Navigation URL Choosen');
    this.activeRouteTitle = currentRoute.snapshot.data['title'];
    });
    debugger;
    }

    ngOnInit() {
    if (navigator.userAgent.indexOf('.NET') != -1) {
    this.supported = false;
    }
    console.log("App Component NgOnInit");
    debugger;
    }

    ngOnDestroy() {
    console.log('AppComponent destroyed');
    debugger;
    }

    toggleMenu(event: any) {
    let el = event.target;
    if (el.classList.contains('toggle-nav')) {
    return;
    }
    this.menuToggle = el.id == 'menu-toggler' ? !this.menuToggle : false;
    }
    }



    app.routing.ts:


    import { NgModule } from '@angular/core';
    import { RouterModule, Routes } from '@angular/router';
    import { AllocationsComponent } from './allocations/allocations.component';
    import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
    import { CanDeactivateGuard } from './shared/routing.guards';

    const routes: Routes = [
    { path: '', redirectTo: '/allocations', pathMatch: 'full' },
    {
    path: 'allocations',
    component: AllocationsComponent,
    canDeactivate: [CanDeactivateGuard],
    data: { title: 'Allocations' }
    },
    { path: '**', component: PageNotFoundComponent },
    ];

    @NgModule({
    imports: [RouterModule.forRoot(routes, { enableTracing: true })],
    exports: [RouterModule]
    })
    export class AppRoutingModule {
    constructor() {
    console.log('AppRoutingModule loaded');
    }
    }




    index.html


    <!DOCTYPE html>
    <html lang="en">

    <head>
    <meta charset="utf-8">
    <title>App</title>
    <base href="/static/src/dist/dev/">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="shortcut icon" sizes="16x16" href="/public/favicon.ico" type="image/jpeg" />

    </head>

    <body>
    <app-root>
    <nav id="header" class="navbar navbar-expand-md" (click)="toggleMenu($event)">
    <div class="navbar-brand">{{ activeRouteTitle }}</div>
    <ul id="menu-navbar" class="navbar-nav mr-auto main-menu toggle-nav" [class.active]="menuToggle">
    <li class="nav-item toggle-nav">
    <a class="nav-link" routerLink="/allocations" routerLinkActive="active"><span>Allocations</span></a>
    </li>
    <li class="nav-item toggle-nav">
    <a class="nav-link" routerLink="/validation" routerLinkActive="active"><span>Validation</span></a>
    </li>
    <li class="nav-item toggle-nav">
    <a class="nav-link" routerLink="/groups" routerLinkActive="active"><span>Resources</span></a>
    </li>
    <li class="nav-item toggle-nav">
    <a class="nav-link" routerLink="/projects" routerLinkActive="active"><span>Projects</span></a>
    </li>
    <li class="nav-item toggle-nav">
    <a class="nav-link" routerLink="/export" routerLinkActive="active"><span>Export</span></a>
    </li>
    </ul>
    <div class="menu-hamburger"><i id="menu-toggler" class="fa fa-bars" aria-hidden="true"></i></div>
    </nav>
    <div *ngIf="!supported" class="ie-info"><span>Internet Explorer is not a&nbsp;supported browser. </span></div>
    <div class="ispinner ispinner--gray ispinner--animating ispinner--large">
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    <div class="ispinner__blade"></div>
    </div>
    <div (click)="menuToggle = false">
    <ng-template ngbModalContainer></ng-template>
    <router-outlet></router-outlet>
    </div>
    </app-root>
    </body>
    </html>



    Tried removing from app.module.ts the bootstrap AppComponent and loop is gonne, but system don't work.

    Continue reading...

Compartilhe esta Página