12

I have a parent and child component where the parent is passing an object to the child through the @Input decorator. The problem is the child gets the parent data only once, then after future changes to parent property that is passed to the child, the value is not being update.

WasiF
  • 26,101
  • 16
  • 120
  • 128
user2385716
  • 121
  • 1
  • 1
  • 3

6 Answers6

14

On parent component change, do change in child component too

Here is how you can do with OnChanges interface which detects changes in the component

In parent.component.html

<app-child [child_name]="name"></app-child>

In child.component.ts

export class ChildComponent implements OnChanges {

  @Input('child_name') name: string
  text: string
  constructor() { }

  // on every change of @input 'name', this method will be triggered
  ngOnChanges() {
    this.text = 'Hi ' + this.name
  }

}

DEMO

WasiF
  • 26,101
  • 16
  • 120
  • 128
7

The data will be updated when whole reference will be updated. If you just update some properties inside that object, it will not be triggered. You need to change the reference of the passed object.

Example

<child [data]="myData"></child>

If you will update myData.name = "Test", it will not be triggered. You need to do something

this.myData = changedData;

A workaround can be using DoCheck lifecycle hook and try to check the property change manually. But generally it is more handy to change the reference.

Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
  • 1
    this will not work if you update value in parent ...try at your end – Pranay Rana Mar 13 '18 at 06:30
  • I have tried. Your answer is not related to this. It is about change detection strategy. When you set it to `OnPush`, change detection will only look at your component when `@Input`-s are changed or the change is in that component. – Suren Srapyan Mar 13 '18 at 06:31
  • if you want to get update for each property change than it will work , in your case i think it will pass value once only , there is change in prop value by parent component it will not reflect in child component ..i tried that – Pranay Rana Mar 13 '18 at 06:33
  • Angular does not look for property changes. It looks only when reference is changed – Suren Srapyan Mar 13 '18 at 06:34
  • i know but when you want your child component to listen for changes done by parent in passedproperty value than i think it will not work , in my case it worked by adding line, we can go on plunker and check, it will be learning for me if your solution works – Pranay Rana Mar 13 '18 at 06:36
  • @PranayRana Please read https://stackoverflow.com/questions/34124735/in-angular2-how-to-get-onchanges-for-properties-changed-on-an-object-sent-in-fo – Suren Srapyan Mar 13 '18 at 06:37
  • You could implement the ngDoCheck() method in your MyDirective class. That lifecycle hook is called "every time that the input properties of a component or a directive are checked. Use it to extend change detection by performing a custom check.", this from the answer – Pranay Rana Mar 13 '18 at 06:38
  • if you put changDetection then you dont need to put that it will work without adding – Pranay Rana Mar 13 '18 at 06:39
  • Let to not agree with you. What will not work with my approach ? – Suren Srapyan Mar 13 '18 at 06:39
  • ok no issues , plunker is good soruce we can try out thing if you want – Pranay Rana Mar 13 '18 at 06:40
  • @PranayRana Ok. – Suren Srapyan Mar 13 '18 at 06:41
  • @PranayRana `this will not work if you update value in parent` Can you show us an example please? – yurzui Mar 13 '18 at 06:46
  • @yurzui - if you check my answer , in that if you remove changDetection thing from child component , and try its not working ..i have one screen in my project where when value of variable passed by parent changes than in child component it will not detect change automatically , there are way to listen that change one of the way which is given by me and other way is to listen change events ...in my case just adding changDetection worked – Pranay Rana Mar 13 '18 at 06:54
  • 1
    @yurzui - i can show you but i dont have access to plunker in working envrionment ... will paste link here once reach home – Pranay Rana Mar 13 '18 at 06:57
2

if you want to get update value from parent compoent than you need to add changeDetection: ChangeDetectionStrategy.OnPush in your child component

Note: OnPush works by comparing references of the inputs of the component

@Component({
  selector: 'abc',
  templateUrl: 'component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class childComponent {
   //below get updated value every time value changes in parent  
   @Input() inputFromParent: string;
}

in parent , use child component abc

 <abc [inputFromParent]="passdata"></abc>

in parent ts this.inputFromParent = newData;//done after first init

now if you change value of passdata then it will change value in childcomponent property too.

Ref : Understanding Change Detection Strategy in Angular

Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
1

your parent comp html looks like :

<div>
        <span (click)="expandAllClient = true "> EXPAND </span>
        <span (click)="expandAllClient = false"> COLLAPSE </span>
</div>
<div>
    <child-comp [expandAll]="expandAllClient"(flagChanged)="flagChanged($event)"></child-comp>
</div>

and dont forget to add :

@Input() expandAll: boolean = false; in your ts file

and in child comp you can directly use expandall(here) in all your operation like:

<div [ngClass]="{'openPanel':  expandAll}></div>

here openpanel class will get applied if you have clicked EXPAND span in parent component

T. Shashwat
  • 1,135
  • 10
  • 23
1

Try to get the changes by ngOnChanges

use it in the child component

  ngOnChanges(changes: import("@angular/core").SimpleChanges): void {

}
Mohammad Hassani
  • 511
  • 6
  • 14
0

you should read about change detection.

if you want to change data from parent component and others use service or ngrx-store also you can use redux

Jamshed
  • 290
  • 1
  • 8