Lee Winder Lee Winder - 8 months ago 51
HTML Question

Angular 2 - Injecting a component created by a HTML selector

I am trying to access a component that has been created using a selector within some HTML. I was under the impression (wrongly it seems) that providers would look for an existing instance and provide that when injected into another component, but obviously I am misunderstanding the hierarchical provider creation process.

In the following, I have a component, which uses a selector within its template HTML to create an instance of TopLevelComponent.

I am trying to access that TopLevelComponent by creating a provider and using DI to push that instance through the constructor.

(Apologies if this code is not perfect, I have just put together a quick example.)

selector: 'my-app',
template: '<top-level-component></top-level-component>',

directives: [TopLevelComponent],
providers: [TopLevelComponent],
export class MyApp {

constructor( private topLevelComponent: TopLevelComponent) {


selector: 'top-level-component',
template: '',
export class TopLevelComponent {

constructor() {
console.log('CONSTRUCTED A TopLevelComponent...');


But, instead of getting one instance of TopLevelComponent passed to my component I get two (as evidenced by the two logs of 'CONSTRUCTED A TopLevelComponent...' present in the debug log).

If I remove 'private topLevelComponent: TopLevelComponent' from the constructor, I only get one instance of the component, but I don't seem to be able to get hold of this.

So I have two questions

  • How do I use DI to pass in the instance of the selector created component to the constructor of other components


  • If I don't include
    in the app HTML, how can I inject that HTML into the app so it renders correctly?

And a third

  • If both of the above are possible, which is the recommended method?

I was thinking @ViewChild would be the right method, as there will(!) only be one instance of this component, but as it's injected into a number of different components, I don't think that's possible.


If you add a component to providers: [...] then the component is treated like a plain class. If DI finds such a provider when TopLevelComponent is requested it creates an instance of the component class @Component(...) decorator is ignored.

If a component is listed in directives: [...] DI will find them as components and directives if they were instantiated because of matching selectors.


  <component-to-inject #source></component-to-inject>
  <component-to-receive [injectedComponent]="source"></component-to-receive>


export class ReceivingComponent { 

  @Input() injectedComponent: InjectingComponent;

  ngOnInit() {