Angular 2 Component @ Input not working

I am trying to pass a property value to my component. From what I read, everything looks right. But it still does not work. My test value is displayed on the screen and the console as null .: (

This is my test component:

import {Component, Input} from 'angular2/angular2'; @Component({ selector: 'TestCmp', template: `Test Value : {{test}}` }) export class TestCmp { @Input() test: string; constructor() { console.log('This if the value for user-id: ' + this.test); } } 

This is how I call the component from the parent page.

 <TestCmp [test]='Blue32'></TestCmp> 

When the page is displayed, the test value is empty. I see only "Test Value:".

Instead of "Test Value: Blue32".

+64
javascript angular typescript
Oct. 25 '15 at 5:01
source share
9 answers

You have four things that I can note:

  • You pass the input to the root component, which will not work.
  • As mentioned in @alexpods, you are using CamelCase. You should not.
  • You pass an expression instead of a string through [test] . This means that angular2 is looking for a variable named Blue32 instead of passing the raw string.
  • You are using a constructor. This will not work, it should be after the view is initialized . The data binding properties were initialized (see Docs for OnInit ).

So with some fixes it should work

Example updated to beta 1

 import {Component, Input} from 'angular2/core'; import {bootstrap} from 'angular2/platform/browser'; @Component({ selector : 'childcmp', template: `Test Value : {{test}}` }) class ChildCmp { @Input() test: string; ngOnInit() { console.log('This if the value for user-id: ' + this.test); } } @Component({ selector: 'testcmp', template : `<childcmp [test]="'Blue32'"></childcmp>` directives : [ChildCmp] }) export class TestCmp {} bootstrap(TestCmp); 

See plnkr for an example.

Update

I see that people are still reaching this answer, so I upgraded plnkr to beta 1 and I fixed one point of explanation: you can access the inputs in ngAfterViewInit, but you can access them earlier in the life cycle in ngOnInit.

+121
Oct 25 '15 at 12:27
source share
β€” -

It is as simple as wrapping the string in double quotes, like this:

 <TestCmp [test]="'Blue32'"></TestCmp> 
+8
Aug 21 '17 at 12:21
source share

This angular class can do the trick for static attributes: ElementRef https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html

 import {ElementRef} from 'angular2/core' constructor(elementRef: ElementRef) { elementRef.nativeElement.getAttribute('api') } 
+5
Jan 25 '16 at 9:25
source share

If you use brackets [], Angular uses property bindings and expects to get the expression inside quotation marks, and also looks for the Blue32 property from your component's class or variable inside the template.

If you want to pass a string as a value to a child component, you can pass it as follows:

 <child-component childProperty='passing string'></child-component> 

or

 <child-component [childProperty]="'note double quotes'"></child-component> 

And then transfer it to child.component.ts as follows:

 import { Component, Input } from "@angular/core"; @Component({}) export class ChildComponent { @Input() childProperty: string; } 
+5
Apr 19 '18 at 6:28
source share

I believe that the problem here may be related to the life cycle of the page. Since inside the constructor, this.test is null. But if I add a button to the template associated with a function that pushes the value to the console (the same as what I do in the constructor) this.test will really matter.

+2
Oct. 25 '15 at 5:48
source share

It may look like a hammer, but you can put an input wrapped in an object like this:

 <TestCmp [test]='{color: 'Blue32'}'></TestCmp> 

and change your class

 class ChildCmp { @Input() test: any; ngOnInit() { console.log('This if the value for user-id: ' + this.test); } } 
+1
Jul 23 '16 at 22:51
source share

Share what worked for me:

Adding input to an Angular 4 application

Assuming we have 2 components:

  • parent-component
  • child-component

We wanted to pass some value from parent-component to child-component , i.e. @Input from parent-component.html to child-component.ts . The following is an example explaining the implementation:

parent-component.html looks like this:

<child-component [someInputValue]="someInputValue"></child-component>

parent-component.ts looks like this:

 class ParentComponent { someInputValue = 'Some Input Value'; } 

child-component.html looks like this:

<p>Some Input Value {{someInputValue}}</p>

child-component.ts looks like this:

 import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'child-component', templateUrl: './child-component.html' }) export class ChildComponent implements OnInit { @Input() someInputValue: String = "Some default value"; @Input() set setSomeInputValue(val) { this.someInputValue += " modified"; } constructor() { console.log('someInputValue in constructor ************** ', this.someInputValue); //someInputValue in constructor ************** undefined } ngOnInit() { console.log('someInputValue in ngOnInit ************** ', this.someInputValue); //someInputValue in ngOnInit ************** Some Input Value } } 

Note that the @Input value @Input available inside ngOnInit() and not inside constructor() .

Object Reference Behavior in Angular 2/4

In Javascript, objects are stored as links .

This exact behavior can be replayed using Angular 2/4. The following is an example explaining the implementation:

parent-component.ts looks like this:

 class ParentComponent { someInputValue = {input: 'Some Input Value'}; } 

parent-component.html looks like this:

 {{someInputValue.input}} 

child-component.html looks like this:



Some Input Value {{someInputValue}}

change input

child-component.ts looks like this:

 import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'child-component', templateUrl: './child-component.html' }) export class ChildComponent implements OnInit { @Input() someInputValue = {input:"Some default value"}; @Input() set setSomeInputValue(val) { this.someInputValue.input += " set from setter"; } constructor() { console.log('someInputValue in constructor ************** ', this.someInputValue); //someInputValue in constructor ************** undefined } ngOnInit() { console.log('someInputValue in ngOnInit ************** ', this.someInputValue); //someInputValue in ngOnInit ************** Some Input Value } changeInput(){ this.someInputValue.input += " changed"; } } 

The changeInput() function will change the value of someInputValue inside ChildComponent and ParentComponent due to their reference. Since someInputValue refers to the ParentComponent someInputValue object - a change in the ChildComponent someInputValue object changes the value of the ParentComponent someInputValue object . IT IS NOT RIGHT. Links will never be changed.

+1
Aug 14 '17 at 19:30
source share

you need to import input like this at the top of the child component

 import { Directive, Component, OnInit, Input } from '@angular/core'; 
0
Dec 31 '16 at 8:49
source share

When you use @Input for angular interaction. Always the preferred approach for transferring data from parent to child in a JSON object, apparently it does not restrict @Angular Team to use a local variable or a static variable.

In the context of accessing the value of a child component, use the ngOnInit () {} angular lifecycle loop , regardless of constructor.

This will help you. Greetings.

0
Jul 15 '17 at 8:18
source share



All Articles