Search code examples
angulartypescripttsc

Angular2 - Compilation issue with nested component


I have two Angular2 components coded with TypeScript:

app/app.component.ts

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

@Component({
    selector: 'my-app',
    styles : [`
        .parent {
            background : #c7c7c7;
            color : #000;
            padding: 20px;
        }
    `],
    template: `
        <div class="parent">
            <h1>{{name}}</h1>
        </div>
    `,
})
export class AppComponent { name = 'Angular'; }

app/child.components.ts

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

@Component({
    selector: 'child-component',
    styles : [`
        .child {
            background : #aaa;
            padding: 10px;
        }
    `],
    template: `
        <div class="child">
            <h2>{{name}}</h2>
        </div>
    `,
})
export class ChildComponent {
    name = "Child Component";
}

If in the component app/app.component.ts I don't nest the component: app/child.components.ts everything compiles correctly.

Please, check here:

http://plnkr.co/edit/5PfPmDoUkxYRirCtwSGa?p=preview&open=app%2Fapp.component.ts

But if I nest it, then I think the transpiler is unable compile...

app/app.component.ts (nesting: app/child.components.ts)

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

@Component({
    selector: 'my-app',
    styles : [`
        .parent {
            background : #c7c7c7;
            color : #000;
            padding: 20px;
        }
    `],
    template: `
        <div class="parent">
            <h1>{{name}}</h1>
            <child-component></child-component>
        </div>
    `,
    directives: [ChildComponent]
})
export class AppComponent { name = 'Angular'; }

Please, check here:

http://plnkr.co/edit/qpsYQx4Ih4qQ1dyk3tFH?p=preview&open=app%2Fapp.component.ts

My questions are:

1- What is failing on the above code?

2- Is there a way I can check an error log of the TypeScript transpiler to see what's going on when there are transpilation issues like here?


Solution

  • Well, feeling nice today ;)

    You are missing two big pieces in your app. BTW, Plunker has preset Angular 2 templates, from which you can start playing around. So what you were missing was a NgModule and main.ts-file.

    You can read more about NgModule here, but as an excerpt from that page:

    An Angular module is a class decorated with @NgModule metadata.

    The metadata:

    • declare which components, directives and pipes belong to the module.
    • make some of those classes public so that other component templates can use them.
    • import other modules with the components, directives and pipes needed by the components in this module.
    • provide services at the application level that any application component can use.

    Since you have a child component, you also need to add CUSTOM_ELEMENTS_SCHEMA, since you have the <child-component> tag, i.e element. Here would be the NgModule that would work for you, so very minimal:

    @NgModule({
      imports: [
        BrowserModule,
      ],
      declarations: [
        AppComponent
        ChildComponent,
      ],
      bootstrap: [ AppComponent ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
    })
    
    export class AppModule { }
    

    Other missing file was main.ts, which launches the application.

    import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
    import {AppModule} from './app';
    
    platformBrowserDynamic().bootstrapModule(AppModule)
    

    Your components were almost correct. But we don't use "directives" anymore, everything is taken care of in the NgModule.

    Here's a Plunker

    As I said, I really suggest you start from the beginning of the tutorial from Angular.io The tutorial is very good in my opinion!