Search code examples
angularangular-servicesangular-componentsangular-module

Cannot use a Component declared in a "CoreModule" but can use services


I am trying to follow the angular docs so that I only have one instance of a specific module. Specifically the CoreModule and the SharedModule sections.

The demo at the bottom of the links above works for only importing CoreModule once in the AppModule, where the lazy loaded HeroesModule and HeroComponent can reference the UserService declared in the CoreModule

My problem comes in when trying to use a Component that has been declared and exported from a "CoreModule".

For example the default HeroComponent works like:

// Exact copy except import UserService from core
import { Component }   from '@angular/core';

import { HeroService } from './hero.service';
import { UserService } from '../core/user.service';

@Component({
  template: `
    <h2>Heroes of {{userName}}</h2>
    <router-outlet></router-outlet>
  `,
  providers: [ HeroService ]
})
export class HeroComponent {
  userName = '';
  constructor(userService: UserService) {
    this.userName = userService.userName;
  }
}

but if I modify it to include the app-title component declared in the CoreModule it breaks with the error 'app-title' is not a known element

// Exact copy except import UserService from core
import { Component }   from '@angular/core';

import { HeroService } from './hero.service';
import { UserService } from '../core/user.service';

@Component({
  template: `
    <h2>Heroes of {{userName}}</h2>
    <router-outlet></router-outlet>
    <app-title></app-title>
  `,
  providers: [ HeroService ]
})
export class HeroComponent {
  userName = '';
  constructor(userService: UserService) {
    this.userName = userService.userName;
  }
}

I have copied the example from the angular.io docs below, and have only modified the app/hero/hero.component.ts template to include <app-title></app-title>,

Example: click the "Heroes" button after the app loads

https://plnkr.co/edit/SZOEvdRCT23S4DfbGmut?p=preview

edit: second example, click "Contact" after the app loads

https://stackblitz.com/edit/angular-2ym6ya?file=contact/contact.component.html

Any suggestions on getting the components from CoreModule to work in lazy loaded modules, or information on why I shouldn't expect this to work would be greatly appreciated.


Solution

  • To use components, directives, or pipes from a module, you need to add the module that provides them to imports: [...], to every module where they are used.

    Services are hoisted in the application root scope, if provided or imported by the AppModule, or in the root scope of the lazy loaded module that imports them (lazy loaded modules introduces a child scope to the application root scope), and therefore only need to be imported once.

    https://stackblitz.com/edit/angular-ds2rce?file=core%2Fcore.module.ts