Angular2 subscribing to changes to @Input in Child Component

As mentioned in the other answer, you can use ngOnChanges life hook. From Angular`s documentation:

ngOnChanges: Respond after Angular sets a data-bound input property. The method receives a changes object of current and previous values.

Check the example below to see how you can use it:

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

@Component({
  selector: 'child',
  template: `
    Value:
    <span>{{ value }}</span>
    <br />
    <br />
    Number of changes: {{ numberOfChanges }}
  `
})
export class ChildComponent implements OnChanges {
  @Input() value: any;

  private numberOfChanges: number = 0;

  ngOnChanges() {
    this.numberOfChanges++;
  }
}

Plunker: http://plnkr.co/edit/XjD1jjCnqiFdbhpTibIe


Another solution for "transforming" the changing value into an observable should be

@Input() status: Status;
private status$: Subject<Status>;

constructor() {
    this.status$ = new Subject<Status>();
}

ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {

    this.status.next(this.status);
}

ngOnChange is called each time an input parameter changes. You even have it in your Child component, but it's not implemented correctly:

ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
  // check the object "changes" for new data
}

More details: https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#onchanges

Update: index in the parent component is a string. For some reason it became an Observable in the child component.


https://angular.io/docs/ts/latest/api/core/index/Input-var.html

To quote:

Angular automatically updates data-bound properties during change detection.

If you need to do some processing on the input, look at the get and set. https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter

From the documentation, here is an example.

import { Component, Input } from '@angular/core';
@Component({
  selector: 'name-child',
  template: `
    <h3>"{{name}}"</h3>
  `
})
export class NameChildComponent {
  _name: string = '<no name set>';
  @Input()
  set name(name: string) {
    this._name = (name && name.trim()) || '<no name set>';
  }
  get name() { return this._name; }
}

You don't need to use an observable.

Tags:

Angular