5

In a simplified way I have an Angular2 Component and an input object like this:

class MyObject{
 Prop1:string;
 Prop2:Number;
}  

@Component() 
export class MyComponent{
 @Input() myObject: MyObject;
 DoSomethingIfProp1Change(){
  console.log(myObject.Prop1);
 }
}

How can I detect if Prop1 was changed from Hostcomponent and then execute the DoSomethingIfProp1Change method from inside MyComponent?

1
  • I updated my answer (fixed some errors and added a working Plunker example). Commented Mar 29, 2016 at 5:43

2 Answers 2

5

In fact, by default Angular2 detects changes when object reference is updated not its content. But this default behavior can be changed by using the DoCheck interface.

In your case (detecting that a property was updated into the myObject object, you could use the following approach:

@Component({
  selector: 'my-component',
  (...)
}) 
export class MyComponent implements DoCheck {
  @Input() myObject: MyObject;
  differ: any;

  constructor(differs:  KeyValueDiffers) {
    this.differ = differs.find([]).create(null);
  }

  ngDoCheck() {
    var changes = this.differ.diff(this.myObject);

    if (changes) {
      changes.forEachChangedItem((elt) => {
        if (elt.key === 'prop1') {
          this.doSomethingIfProp1Change();
        }
      });
    }
  }

  doSomethingIfProp1Change() {
    console.log('doSomethingIfProp1Change');
  }
}

When the value of the prop1 property is updated, the doSomethingIfProp1Change method is called.

See this plunkr: http://plnkr.co/edit/uvOKMXQa9Ik8EiIhb60Y?p=preview.

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

1 Comment

Trying to understand what this is actually doing but in the meantime, I'm getting an error on the line in the constructor, create expects no arguments.
4

You can use observables to support notification of subscribers. Angular itself doesn't provide support for observing changes of internal object state.

class MyObject{
  constructor() {
    this.prop1Change$ = new Observable(observer => 
        this._prop1Observer = observer).share(); // share() allows multiple subscribers

    this.prop2Change$ = new Observable(observer =>
        this._prop2Observer = observer).share();
        console.debug(this._prop2Observer);
  }

  prop1Change$: Observable<string>;
  private _prop1Observer: Observer;
  _prop1:string;
  get prop1():string { return this._prop1 };
  set prop1(value:string) {
    this._prop1 = value;
    this._prop1Observer && this._prop1Observer.next(value);
  }

  prop1Change$: Observable<number>;
  private _prop2Observer: Observer;
  _prop2:Number;
  get prop2():number { return this._prop2 };
  set prop2(value:number) {
    this._prop2 = value;
    console.debug(this);
    this._prop2Observer && this._prop2Observer.next(value);
  }
}

This code could be shortened by using Subject but Observable should be favored over Subject.

@Component() 
export class MyComponent{
  @Input() myObject: MyObject;

  count2:number;

  DoSomethingIfProp1Change(){
    console.log(myObject.prop1);
  }

  ngOnChanges(changes: {[propName: string]: SimpleChange}) {
    console.log('changes');
    if(changes['myObject']) {
      if(this.prop2Subscription) {
        this.prop2Subscription.unsubscribe();
      }
      this.prop2Subscription = this.myObject.prop2Change$.subscribe(value => {
        this.count2 = value;
        console.log('count2: ' + value);
      });
      // same for `prop2`
    }
  }
}

Plunker example

See also Delegation: EventEmitter or Observable in Angular2

4 Comments

Hi gunter, on the link you provide, an update recommend to use Subject, what would you advice in terms of best practice ?
@ThomasP1988 Not sure what you mean. EventEmitter is for @Output()s only. What else is unclear about best practice?
in the link your provided 'Delegation: EventEmitter or Observable in Angular2' the best answer recommends to use BehaviorSubject instead of observable. Do you agree with that ?
That depends no your requirements. There is a difference between BehaviorSubject and Subject. BehaviorSubject emits the last emitted value immediately to new subscribers. This is useful if the first event was emitted before the subscriber subscribed. With Subject you only get notified when another event is emitted while BehaviorSubject immediately replays the last event. Observable is a more barebone version of Subject. It's usually considered better practice to use Observable instead of Subject but Subject is a bit easier to set up.

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.