Search code examples
htmlangulartypescriptcomponents

Angular Component gets looped


Im building an Angular application and my navbar gets looped. My problem is, that if I am on /home, the navbar.component.html components gets looped and i see 2 among each other. How can I solve this

import {Routes} from '@angular/router';
import {HomeComponent} from "./home/home.component";
import {AdminComponent} from "./admin/admin.component";

export const routes: Routes = [
  {path: 'home', title: 'Home', component: HomeComponent},
  {path: 'admin', title: 'Admin', component: AdminComponent},
  {path: '**', redirectTo: 'home'},
];

app.modules.ts

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {NavbarComponent} from "./navbar/navbar.component";
import {AdminComponent} from "./admin/admin.component";
import {RouterLink, RouterModule, RouterOutlet} from "@angular/router";

@NgModule({
  declarations: [AdminComponent, NavbarComponent],
  imports: [CommonModule, RouterLink, RouterOutlet, RouterModule],
  exports: [AdminComponent, NavbarComponent, CommonModule, RouterLink, RouterOutlet, RouterModule]
})
export class AppModule {
}

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Ui</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<app-home></app-home>
<router-outlet></router-outlet>
</body>
</html>

home.component.html

<app-navbar></app-navbar>
<router-outlet></router-outlet>

navbar.component.html

<nav>
  <ul>
    <li><a routerLink="/home" >Home</a></li>
    <li><a routerLink="/news">News</a></li>
    <li><a routerLink="/contact">Contact</a></li>
    <li><a routerLink="/about">About</a></li>
    <li><a routerLink="/admin">Admin</a></li>
  </ul>
</nav>

I tried changing the router outlet many times and changing where I use which component but I cant bring it to work.

Heres the whole repository: https://stackblitz.com/~/github.com/leningl-bzz/Import-Project


Solution

  • UPDATE

    The reason you are getting this problem is because, you have bootstrap HomeComponent which is ok, but you are referencing the same home component in routing, which is the default route, this is why the navbar is coming twice.

    The fix for this issue, is to define an AppComponent which will act as the root component, which will store the navbar and load the child components inside it!

    ts

    import { Component } from '@angular/core';
    import { AppModule } from '../app.module';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [AppModule],
      templateUrl: './app.component.html',
      styleUrl: './app.component.css'
    })
    export class AppComponent {
    
    }
    

    app html

    <app-navbar></app-navbar>
    <router-outlet></router-outlet>
    

    index.html

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>Ui</title>
      <base href="/">
      <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <app-root></app-root>
    </body>
    </html>
    

    main.ts

    import { bootstrapApplication } from '@angular/platform-browser';
    import { config } from './app/app.config.server';
    import { AppComponent } from './app/app/app.component';
    
    const bootstrap = () => bootstrapApplication(AppComponent,  config);
    
    export default bootstrap;
    

    main.server.ts

    import { bootstrapApplication } from '@angular/platform-browser';
    import { appConfig } from './app/app.config';
    import { AppComponent } from './app/app/app.component';
    
    bootstrapApplication(AppComponent, appConfig)
      .catch((err) => console.error(err));
    

    stackblitz demo


    Can you modify the index.html so that it only contains the main bootstrapped component, either the one used in bootstrap array of modules or the component used in bootstrapApplication!

    index.html

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>Ui</title>
      <base href="/">
      <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <app-home></app-home> <!-- assuming this is the bootstrap main component of your application! -->
    </body>
    </html>