7

There are 2 components: parentComponent and ChildComponent, which is defined inside the parent. In the parentComponent there is a local variable which is used as value to pass to an input property of the ChildComponent (using a getter).

ParentComponent.ts:

@Component({
selector:'parent-component',
template:`
<h1>parent component</h1>
<child-component [personData]="PersonData"></child-component>
`
})
export class ParentComponent{
personData:Person;

get PersonData():Person{
return this.personData;
}

set PersonData(person:Person){
this.personData = person;
}

ngOnInit(){
this.PersonData = new Person();
this.PersonData.firstName = "David";
}

//more code here...

}

ChildComponent.ts:

@Component({
    selector:'child-component',
    template:`
    <h1>child component</h1>
    <div *ngIf="personData">{{personData.firstName}}</div>
    `
    })
export class ChildComponent{
    @Input() personData:Person;        

    //more code here...

 }

The issue is: in some place in the parent component, when specific event occurs, a function newPersonArrived(newPerson:PersonData) is being called, the function code is as following:

newPersonArrived(newPerson:Person){
    this.PersonData = newPerson;
    }

This doesn't affect the UI with the new person name!

Only the following helps:

newPersonArrived(newPerson:Person){
    this.PersonData = new Person();
    this.PersonData.firstName = newPerson.firstName;
    }

Is this the expected behavior?

why only when the personData is initialized to new Person, the UI "catches" the change?

tanmay
  • 7,761
  • 2
  • 19
  • 38
Batsheva
  • 659
  • 4
  • 13
  • 27
  • Where do you call `newPersonArrived`? It should work – yurzui May 09 '17 at 06:26
  • After some event occurs in the parent component, I see that the functin is being called (I put there console.log('aa') and saw it was printed) – Batsheva May 09 '17 at 06:28
  • https://plnkr.co/edit/0SVsezfJYtc0xzKGkAZe?p=preview – yurzui May 09 '17 at 06:28
  • I see the example, so do you mean this is depends from which event I am coming? sounds interesting – Batsheva May 09 '17 at 06:46
  • I don't know exactly. To better understand it we need some working example – yurzui May 09 '17 at 06:48
  • It is very strange, I simulated in Plunker the full example, but there is seems to update the UI - in my local dev environment only the sceond way works as I describe in the question. this is the plunker:https://plnkr.co/edit/IxIJ5e8jhCq03TFfosjc?p=preview . The only difference I can see is the angular version - I use 4.0.2 – Batsheva May 09 '17 at 07:45

1 Answers1

7

please watch for your changes in child component

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

@Component({
    selector:'child-component',
    template:`
    <h1>child component</h1>
    <div *ngIf="personData">{{personData.firstName}}</div>
    `
    })
export class ChildComponent implements OnChanges{
    @Input() personData:Person; 
     public ngOnChanges(changes: SimpleChanges) {
          if ('personData' in changes) {
              //some code here
           }
      }       

    //more code here...

 }
sainu
  • 2,686
  • 3
  • 22
  • 41
  • I tried this, but the ngOnChanges is not being called in the first way I tried (this.PersonData = newPerson), only if I do the new Person(), but in this case, the UI is updated and I don't need the ngOnChanges.... – Batsheva May 09 '17 at 06:42
  • This worked for me. I couldn't 'push' the latest data to the child if the parent data changed rapidly. The OnChanges worked a treat. Thanks. – spankymac Jun 04 '18 at 04:36
  • Worked for me like a charm – Hamid Noahdi Apr 20 '21 at 16:49