4

I have just started learning Angular and working through some tutorials. My project is generated by Angular CLI. I have generated a new component called navbar on top of the component that was generated when I created the project and I was trying to see if navbar loads up on my index.html upon start up. My navbar shows up only when I have both app in the index.html file, for example:

<body>
  <app-root></app-root>
  <app-navbar></app-navbar>
</body>

If I remove app-root from index.html like so:

<body>
  <app-navbar></app-navbar>
</body>

My navbar app is not showing it anymore. Is that something that has to do with the app-root component? Is it because it is a root component and it has to be included in index.html all the time?

Here is my code:

index.html:

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

<head>
  <meta charset="utf-8">
  <title></title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>

<body>
  <app-navbar></app-navbar>
</body>

</html>

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './component1/app.component';
import { NavbarComponent } from './navbar/navbar.component';

@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [
    AppComponent,
    NavbarComponent
  ]
})
export class AppModule { }

navbar.component.ts:

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

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
})
export class NavbarComponent {
  constructor() {}

  // tslint:disable-next-line: use-lifecycle-interface
  ngOnInit() {

  }
}

kaiilim
  • 579
  • 12
  • 31

3 Answers3

1

You must place the component selector inside app.component.html:

<app-navbar></app-navbar>

The <app-root> tag is where the bootstraped component be displayed ( which is the AppComponent by default). And usually you do not need more than 1 bootstraped component, so remove NavbarComponent from bootstrap in AppModule.

In a higher lever view, you can consider your app as a tree of components which it's root is the AppComponent, so the child of AppComponent must be place inside app.component.html, and the child of NavBarComponent for example must be place inside navbar.component.html .

Ethan Vu
  • 2,911
  • 9
  • 25
  • Remove the NavbarComponent from `boostrap ` in AppModule, i updated my answer – Ethan Vu Sep 13 '19 at 03:14
  • why angular team make the bootstrap as an array if that not correct ,the navbar here just a theme component so it 's no harm to move it outside but the angular app bootstrap from a single module check my answer :) – Muhammed Albarmavi Sep 13 '19 at 03:21
1

you can add multiple component to bootstrap but they must be from the same module

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent, NavbarComponent ],
  bootstrap:    [ AppComponent ,NavbarComponent ]
})
export class AppModule { }

index.html

<my-app>loading</my-app>
<app-navbar>loading</app-navbar>

the angular app bootstrap from a single module like appmodule here

main.ts

platformBrowserDynamic().bootstrapModule(AppModule).then(ref => {
  // Ensure Angular destroys itself on hot reloads.
  if (window['ngRef']) {
    window['ngRef'].destroy();
  }
  window['ngRef'] = ref;

  // Otherwise, log the boot error
}).catch(err => console.error(err));

demo ⚡⚡

Muhammed Albarmavi
  • 23,240
  • 8
  • 66
  • 91
  • Why after I remove loading from index.html the navbar stops showing it's content ("navbar works!") instead it's showing "loading". – kaiilim Sep 13 '19 at 03:31
  • try like this `bootstrap: [ NavbarComponent , AppComponent ]` – Muhammed Albarmavi Sep 13 '19 at 03:43
  • 1
    why you add any component to bootstrap list angula will look for that component selector an d throw an error even if any of the component is missing angular expect both component to be presint in the index.htm – Muhammed Albarmavi Sep 13 '19 at 03:46
  • so in your case the error throw before render the other component , I want to ask why do you try this why not just place the navbar in the app component and just bootstrap the app component – Muhammed Albarmavi Sep 13 '19 at 03:49
  • @malbarmavi, for example, if you need Render Angular component outside the main app like this https://stackoverflow.com/questions/38526221/render-angular-component-outside-the-main-app – Andrii Jul 05 '20 at 07:16
1

Angular attempts to find app-root tag and throws error that you can see in console of browser something like this:

Error: The selector "app-root" did not match any elements at ha.selectRootElement (main-*.js)

So rendering crashes, and navbar not showing

To avoid this issue add ngDoBootstrap method with conditionals to root app module:

@NgModule({
  declarations: [],
  imports: [BrowserModule, AppRoutingModule],
  providers: [],
  bootstrap: []
})
export class AppModule
{
  ngDoBootstrap(appRef: ApplicationRef)
  {
    if (document.getElementsByTagName('app-root').length > 0)
    {
      appRef.bootstrap(AppComponent, 'app-root')
    }
    if (document.getElementsByTagName('app-navbar').length > 0)
    {
      appRef.bootstrap(NavbarComponent, 'app-navbar')
    }
  }
}
Andrii
  • 689
  • 1
  • 6
  • 12