0

I have an Input which is a javaScript object. when it changes the ngOnChange doesn't get triggered. I tried a number input, It worked correctly.

export class ResultsComponent implements OnInit, OnChanges {

  @Input() SearchParams: {
    HouseSelected : Boolean,
    ApartementSelected : Boolean,
    ShopSelected : Boolean,
    KolangiSelected : Boolean,
    BusinessSelected : Boolean,
    NumOfRooms : String,
    PriceLow: Number,
    PriceHigh: Number,
    //TODO add City
    MeterLow:Number,
    MeterHigh:Number
  };


  constructor() { }

  ngOnInit() {
  }

  ngOnChanges(changes: SimpleChanges){
    console.log(this.SearchParams);
  }
}

Parent html

<form class="w3-container " >
            <h4>price</h4>
            <div>
            <input name= "priceLow" [(ngModel)]="SearchParams.PriceLow" placeholder="low cost">
            تا
            <input name= "priceHigh" [(ngModel)]="SearchParams.PriceHigh" placeholder="High cost">
            </div>

            <h4>Meter</h4>
            <div>
            <input name= "MeterLow" [(ngModel)]="SearchParams.MeterLow" placeholder="smallest">
            تا
            <input name= "MeterHigh" [(ngModel)]="SearchParams.MeterHigh"  placeholder="Highest">
            </div>

            <div >
              <h4>type</h4>

              <md-checkbox style="width:50%" name=" 1 " [(ngModel)]="SearchParams.HouseSelected">House</md-checkbox>
              <md-checkbox style="width:50%" name=" 2 " [(ngModel)]="SearchParams.ApartementSelected">apartment</md-checkbox>
            </div>

            <h4>room Number/h4>    
            <md-radio-group name="numberOfRooms" [(ngModel)]="SearchParams.NumOfRooms">
              <md-radio-button class="example-margin" value="1">1</md-radio-button>
              <md-radio-button class="example-margin" value="2">2</md-radio-button>
              <md-radio-button class="example-margin" value="3">3</md-radio-button>
              <md-radio-button class="example-margin" value="4">3+</md-radio-button>

          </form>

        </div>
    </div>

    <div>
      <app-results [SearchParams] = "this.SearchParams"></app-results>
    </div>

the child that recives this inputs is app-results( as you can see in the HTML) There's nothing in app-results HTML

3 Answers3

4

The easiest thing to do is create an entirely new object and then assign it to the property that the child's input is bound to, for example.

Parent Component

this.SearchParams = Object.assign({}, NewSearchParams);

You are pretty much encountering the exact same issue as the poster in this question. There are some very good insights into how change detection works in the answers there.

I have learned this lesson the hard way, a couple times :) Javascript passes Objects as reference which is why performing Change Detection on them can be tricky. If you create an entirely new object and overwrite the previous one though, it should trigger change detection.

joshrathke
  • 7,564
  • 7
  • 23
  • 38
1

Its better to trigger change detection by passing new object. For change detection to trigger on object the reference should change to change the reference you need to create new Object. You can use es7 syntax shortcut

object = {
   ...object,
   changeParameter: parameter
 }

and you should change a little bit function

ngOnChanges(changes: SimpleChanges){
console.log(changes)
if (changes.SearchParams) {
 this.SearchParams = changes.SearchParams.currentValue
 console.log(this.SearchParams)
 }
}
alexKhymenko
  • 5,450
  • 23
  • 40
  • @AshkanR.Nejad if you make this 2 requirements at the same time they will work 100%, or wrong passed property in html – alexKhymenko Sep 18 '17 at 19:59
0

Another option to try is to implement ngDoCheck instead of ngOnChanges and write your own change response behavior, see reference : https://angular.io/guide/lifecycle-hooks#docheck

Bob Meijwaard
  • 388
  • 9
  • 20
  • Yep, that didn't work out so well. I couldn't get the desired behavior going. So i changed the post to an alternative that did trigger. – Bob Meijwaard Sep 18 '17 at 20:03