Search code examples
angularangular-components

Angular2: Input setter not picking up set event if value does not change


Referring to Angular2 documentation file here: [https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter] (Parent to child setter), I have the following child component code:

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

And the parent is simple:

import { Component } from '@angular/core';
@Component({
  selector: 'name-parent',
  template: `
  <h2>Parent </h2>
  <name-child [name]="name"></name-child>
  `
})
export class NameParentComponent {
   // somewhere on ngOnInit, set name without changing value
    ngOnInit() { 

        // get pending paged only and so on
        setTimeout(() => {
            this.name = "a";
            setTimeout(() => {
                this.name = "a";
                setTimeout(() => {
                    this.name = "a";
                },1000);

            },1000);

        },1000);
   }
}

You'd expect the console to log out "name change" three times in 3 seconds. It doesn't, it logs it once, and ignores subsequent sets (this happens only if the value does not change). How can I make the input pick up the set event, regardless of whether value changed or not?


Solution

  • I see two ways to solve it:

    1) Use immutable value

    setTimeout(() => {
      this.name = new String("a");
        setTimeout(() => {
          this.name =  new String("a");
          setTimeout(() => {
           this.name =  new String("a");
        }, 1000);
      }, 1000);
    }, 1000);
    

    2) Change input property directly

    @ViewChild(NameChildComponent) child: NameChildComponent;
    
    setTimeout(() => {
      this.child.name = "a";
      setTimeout(() => {
        this.child.name = "a";
        setTimeout(() => {
          this.child.name = "a";
        }, 1000);
      }, 1000);
    }, 1000);