10

How can I do something with the @Input value inside the component??

For example:

<log-user [user]="user"></log-user>

Let's assume that user is an object. Now, I know how I can pass this user data inside te log-user template, but how can I do something with this user inside its component??

LogUserComponent:

@Component({
  selector: 'log-user',
  template: `

    This works: {{user}}

  `
})

export class LogUserComponent {

  @Input() user:any;

  constructor() {
    // this get's logged as undefined??
    console.log(this.user);
  }
}

Any help would be great!! Thanks in advance!

3 Answers 3

17

On construction time the @Input value is not yet set. How could Angular2 set the @Input value before the component was actually constructed?

You have to wait for the component to be initialized; meaning all @Input values have been set. You can do so by implementing the OnInit interface.

So to fix your example:

<log-user [user]="user"></log-user>

(Note: user must be a defined object, otherwise in this example undefined would still be logged. You can add *ngIf="user" to the log-user html tag to ensure the tag does not get rendered before user actually exists.)

Do:

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

@Component({
  selector: 'log-user',
  template: `This works: {{user}}`
})
export class LogUserComponent implements OnInit {

  @Input() user:any;

  ngOnInit() {
    // this now gets logged as 'user'
    console.log(this.user);
  }
}

You can also just create the ngOnInit method on your component without implementing the interface, but by importing the OnInit interface you are ensured by the Typescript compiler not make a typo mistake.

The Angular docs about OnInit states:

Implement this interface to execute custom initialization logic after your directive's data-bound properties have been initialized.

ngOnInit is called right after the directive's data-bound properties have been checked for the first time, and before any of its children have been checked. It is invoked only once when the directive is instantiated.

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

5 Comments

Thanks for your time, but I already tried that, and it still logs as undefined?
Also, instead of passing an object, I tried passing just a string: <log-user [user]="'just a string'"></log-user>. This works and gets logged inside the component. So is there something wrong by passing in an object the way I tried? @Lodewijk
Nope nothing wrong with that. It just must exist before the controller is instantiated.
I've added a note to address this.
This approach isn't working. I did exactly as shown in the example.
7

After some more research, I found this post "@Input property is undefined in angular 2's onInit".

So the answer is actually quite easy. Because in this example the user is an object coming from an API call, it is undefined at initialization of the component (hope I'm saying this the right way).. Using *ngIf fixes this:

<log-user *ngIf="user" [user]="user"></log-user>

1 Comment

Good point. I've added a note to my answer that addresses this point, so that people who have the same kind of question can get the entire answer in one go. Thanks
2

Since our Angular components are ES6 classes with a @Component() decorator we’re able to leverage TS accessors to intercept the injected value as follows:

The main difference is that instead of decorating the property we decorate the setter.

More details http://www.typescriptlang.org/docs/handbook/classes.html

<log-user [user]="user"></log-user>

Inside Component.ts

export class LogUserComponent {
  private _user:any;

  get user() {
    return this._user;
  }
  @Input() 
  set user( user:any) {
    // to catch undefined user 
    if(!user) return;
    this._user = user;
    // modify the user here example below
    // this._user = 'X' + user;
  }

  constructor() {

  }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.