2

Im currently learning angular2 and the ang-book2 suggest that to pass a variable to a child component i should:

In parent view (random_number defined in Parent app.ts):

<app-child
 [passedToChild] = "random_number"
></app-child>

In child component:

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

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css'],
  inputs: ['passedToChild']
})
export class ChildComponent implements OnInit {
  passedToChild :number;

  constructor() { console.log(this.passedToChild)}

  ngOnInit() {
  }

}

This results in undefined output in console.

On the other hand here https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child they use @Input to pass a var to the child element.

The second option seems to work for me but I want to understand why. And neither book nor the page above explains the difference or the reason why the first method results in undefined.

2 Answers 2

1

Using the inputs array on the @Component() configuration object should be the same as adding the @Input() decorator to the property AFAIK, that is not the reason your code doesn't work.

Instead, your problem is that you are checking for the property to be set too early by doing it in the constructor.

Instead, check inside the ngOnInit() method, and the property should have been set for you.

From the docs:

ngOnInit
Initialize the directive/component after Angular first displays the data-bound properties and sets the directive/component's input properties.

Called once, after the first ngOnChanges.

Sign up to request clarification or add additional context in comments.

4 Comments

Got it, the book is inconsistent about the event flow. If i use inputs I don't have to use @Input() annotation like the other user suggested, right? Its the same functionality with different syntax?
I believe so, yes. I couldn't find where in the source this is confirmed, though. Most people using Typescript use the @Input() decorator, so people tend to believe that is the only way to do it. But they need a way to do it so it works without Typescript (however painfully), so all decorators have a plain JS equivalent.
The last thing Im confused with: Should I use @Import explicitly for each variable passed? @Input('randomNumber') mask:number; @Input('anotherRandomNumber') anotherMask:number; Then in Component class console.log(${mask} and ${anotherMask}); Or there's a better way to write it? In my humble newbie opinion its confusing that all examples I find explain the inputs using the same variable name. like <hero-child *ngFor="let hero of heroes" [hero]="hero" [master]="master"> </hero-child> @Input() hero: Hero; @Input('master') masterName: string;
Yes, you need to specify @Input() for each input property. The reason for the same name is usually because what else would you call it? Though I can see the potential for confusion. The important thing to consider is which hero is meant each time. In your example, [hero]="hero" reads as "the hero input property of hero-child is set to the current entry in the heroes array". Does that help?
1

If you want to bind the child property as you have shown, you must annotate the child property with @Input() decorator. If the child property is not decorated with @Input() decorator, then it must be an error in the book.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.