Search code examples
angularng-lightning

ng-lightning with angular2+systemjs and NgModule


I tried to use ng-lightning (0.24.0) with angular2 (2.0.2) and systemjs module loader. The bundle loading is okay I think but when I try to call an ng-lightning template in an ngModule I've got template parse error. From a single component it is workink but inside an ngModule doesn't.

My package.json

"dependencies": {
"@angular/common": "~2.0.2",
"@angular/compiler": "~2.0.2",
"@angular/core": "~2.0.2",
"@angular/http": "~2.0.2",
"@angular/forms": "~2.0.2",
"@angular/platform-browser": "~2.0.2",
"@angular/platform-browser-dynamic": "~2.0.2",
"@angular/router": "~3.0.2",
"@angular/upgrade": "~2.0.2",
"reflect-metadata": "^0.1.8",
"rxjs": "5.0.0-beta.12",
"systemjs": "0.19.39",
"zone.js": "^0.6.25",
"core-js": "^2.4.1",
"@salesforce-ux/design-system": "^2.1.2",
"ng-lightning": "0.24.0",
"tether": "^1.2.4",
},

app.module.ts

import { NgModule }         from '@angular/core';
import { BrowserModule }    from '@angular/platform-browser';
import { FormsModule }      from '@angular/forms';
import { HttpModule, JsonpModule } from '@angular/http';
import { NglModule }        from 'ng-lightning/ng-lightning'

import { AppRoutingModule }  from './app.routing';
import { AppComponent }     from './app.component';
import { TestModule }       from './test/test.module';

@NgModule({
    imports:      [
        BrowserModule,
        FormsModule,
        HttpModule,
        JsonpModule,
        NglModule.forRoot(),
        TestModule,
        AppRoutingModule
    ],
    declarations: [
        AppComponent,
    ],
    bootstrap:    [ AppComponent ]
})
export class AppModule { }

And in TestModule there is a test component and in the test component template theres the template tag.

test.module.ts

import { NgModule }           from '@angular/core';
import { CommonModule }       from '@angular/common';
import { FormsModule }        from '@angular/forms';
import { TestComponent }      from './test.component';
import { TestRoutingModule }  from './test.routing';

@NgModule({
    imports:      [ CommonModule, FormsModule, TestRoutingModule ],
    declarations: [ TestComponent ],
    exports:      [ ],
    providers:    [ ]
})
export class TestModule { }

test.component.ts

import { Component }    from '@angular/core';
@Component({
    moduleId: module.id,
    selector: 'testcomp',
    template: '<ngl-badge></ngl-badge>'
})
export class TestComponent {}

I've got this error:

zone.js:355 Unhandled Promise rejection: Template parse errors:
'my-app' is not a known element:
1. If 'my-app' is an Angular component, then verify that it is part of this module.
2. If 'my-app' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. ("
<body>
<div class="slds">
    [ERROR ->]<my-app>
        <div class="slds-grid slds-grid--align-center">
            <div class="slds-col">
"): TestComponent@21:4 ; Zone: <root> ; Task: Promise.then ; Value: Error: Template parse errors:(…) Error: Template parse errors:

is the main app component template. When I delete tag from my test component template the app works fine. What is the problem? ng-lightning.umd.js loaded correctly as I see in network tab and no error after tsc compiling. So I don't understand.


Solution

  • Angular is built with modularity in mind: this means that each Module should declare or import every component, directive and pipe that it wants to use.

    For the parser to recognize a component, it must have been declared in the current module, or exported by another module that the current module imports. This is why -- for instance -- you had to import FormsModule in both of your modules in the OP.

    Thus you get parsing errors when you try to use ngl-badge in TestComponent because you haven't told Angular that you intend to use ngl-badge when you created TestModule

    Basically, just import what you need into TestModule

    @NgModule({
        imports:      [ CommonModule, FormsModule, 
                        TestRoutingModule, NglModule ],
        declarations: [ TestComponent ],
        exports:      [ ],
        providers:    [ ]
    })
    export class TestModule { }