2

for some reason I can't access to the @Input value of a property even if I try from the ngOnInit() method.

index.html

<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">    

    <!-- 1. Load libraries -->
    <!-- IE required polyfills, in this exact order -->
    <script src="node_modules/es6-shim/es6-shim.min.js"></script>
    <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
    <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>   

    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>

    <!-- 2. Configure SystemJS -->
    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/main')
            .then(null, console.error.bind(console));
    </script>
  </head>

  <!-- 3. Display the application -->
  <body>
    <my-app title="Quick start guide">Loading...</my-app>
  </body>
</html>

main.ts

import { bootstrap } from 'angular2/platform/browser';
import { AppComponent } from './app.component';

bootstrap(AppComponent);

app.component.ts

import {Component, Input, OnInit} from 'angular2/core'

@Component({
  selector: 'my-app',
  template: '<h1>{{ title }}</h1>'
})
export class AppComponent {
    @Input() title: string;

    constructor() {
    }

    ngOnInit() {
        console.log(this.title);
    }
}

That console.log(this.title) is always undefined and the template <h1>{{ title }}</h1> is rendering an empty value.

What I'm missing? I did this a few times before and it always worked.

Cosmin Ababei
  • 7,003
  • 2
  • 20
  • 34
nicowernli
  • 3,250
  • 22
  • 37

2 Answers2

5

@Input() isn't supported on root components.

A workaround using the ElementRef to read the attribute imperatively:

class AppComponent {
    constructor(elm: ElementRef) {
        this.title = elm.nativeElement.getAttribute('title'); 
    }
}

Inputs are only initialized for components or directives that are added to the template of an Angular component. The <body> element is not an Angular component.

See also https://github.com/angular/angular/issues/1858

This issue might also be relevant https://github.com/angular/angular/issues/6370 because the root component is added using DynamicComponentLoader.loadAsRoot()

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
0

Inputs can not be used on the root component (the one you provided when bootstrapping your application) of your application. It's not supported.

You need to reference the attribute by your own using the nativeElement (and its getAttribute method) from the injected ComponentRef in your component.

Something like that:

@Component ({ ... })
 export MyComponent {
   constructor(compRef:ComponentRef) {
     var someAttrValue = compRef.nativeElement.getAttribute('someAttr');
   }
 }
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360