RC0 -Root component is not rendered correctly


#1

I’m wrapping up Meteor and the latest Ionic 2.0.0-rc.0. I migrated my app from Ionic beta.11, got a NgModule like this:

//app.module.ts
@NgModule({
  declarations: [
    SkyFrame
  ],
  imports: [
    IonicModule.forRoot(SkyFrame),
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    SkyFrame
  ],
  providers: [
    METEOR_PROVIDERS
  ]
})
export class AppModule {
}

//main.ts
Meteor.startup(function(): void {
  if (Meteor.isProduction) {
    enableProdMode();
  }
  platformBrowserDynamic().bootstrapModule(AppModule);
});

//app.component.ts
@Component({
    templateUrl: 'app.component.html',
})
export class SkyFrame implements OnInit {

    constructor() {
    }

    ngOnInit():void {
        console.info('This will print endlessly in the console');
    }

}

And when the app starts things go wrong and the call stack is full immediately.
core.umd.js:3372 ORIGINAL EXCEPTION: Maximum call stack size exceeded

When I look at the constructed DOM things go very interesting!
<ion-app> expands into infinite tree with 2 roots! Basically I have two times ng-component which renders itself recursively. I could expand this tree more but would never be able to take whole picture of it :wink:

What I’ve found in Ionic’s code is that the following is repeated thousand of times

//app-root.ts
  ngOnInit() {
    // load the user root component
    // into Ionic's root component
    const factory = this._cfr.resolveComponentFactory(this._userCmp);
    const componentRef = this._viewport.createComponent(factory);
    this._renderer.setElementClass(componentRef.location.nativeElement, 'app-root', true);
    componentRef.changeDetectorRef.detectChanges();
//change detected!! repeat here (insert another ng-component into any found app-root)
...

Nailing it further down createComponent is responsible for rendering:

   ViewContainerRef_.prototype.createComponent = function (componentFactory, index, injector, projectableNodes) {
            if (index === void 0) { index = -1; }
            if (injector === void 0) { injector = null; }
            if (projectableNodes === void 0) { projectableNodes = null; }
            var s = this._createComponentInContainerScope();
            var contextInjector = isPresent(injector) ? injector : this._element.parentInjector;  //contextInjector becomes the parentInjector!
            var componentRef = componentFactory.create(contextInjector, projectableNodes);
            this.insert(componentRef.hostView, index);
            return wtfLeave(s, componentRef);
        };

So parent context is always injected into my component. this._element.parentInjector here is the injector of the root view (<html>)

Not sure if I screwed something up or it’s Ionic bug or it’s Angular. Especially when I’m trying to integrate it all with Meteor. Thus this question posted here not in Ionic’s GitHub.
This combination of libraries is quite fresh so I’m just posting it just in case someone got the same problem.

Package dependencies:

  "dependencies": {
    "@angular/common": "2.0.2",
    "@angular/compiler": "2.0.2",
    "@angular/core": "2.0.2",
    "@angular/forms": "2.0.2",
    "@angular/http": "2.0.2",
    "@angular/platform-browser": "2.0.2",
    "@angular/platform-browser-dynamic": "2.0.2",
    "@angular/router": "3.0.2",
    "angular2-meteor": "0.7.0",
    "angular2-meteor-accounts-ui": "0.8.0",
    "angular2-meteor-polyfills": "^0.1.1",
    "es6-shim": "0.35.1",
    "ionic-angular": "^2.0.0-rc.0",
    "ionicons": "3.0.0",
    "meteor-node-stubs": "0.2.3",
    "reflect-metadata": "0.1.8",
    "rxjs": "5.0.0-beta.12",
    "zone.js": "^0.6.23"
  }