0

I have a parent component which includes a child component. The parent component passes an array to the child. Within the child component I can do several operation on this array. I always create a new array to set the array so everything is updated in the UI. But when I access this array in the parent component, it is not updated at all.

How can I fix this?

Here is a stackblitz for this: https://stackblitz.com/edit/angular-5yah4v

Max
  • 1,053
  • 1
  • 13
  • 34
  • Here is a little stackblitz @ChellappanV https://stackblitz.com/edit/angular-5yah4v – Max Jul 05 '18 at 07:47
  • You must use https://angular.io/guide/component-interaction#parent-listens-for-child-event Output (the EventEmiter is type of EventEmiter) – Eliseo Jul 05 '18 at 08:26
  • what do you want to achive your example working fine – Chellappan வ Jul 05 '18 at 09:00
  • @ChellappanV the first stackblitz was a rudimental demo version. In my real application I am using ag-grid for my list. This seems to be the problem: https://stackblitz.com/edit/angular-jfunyh – Max Jul 05 '18 at 09:03

3 Answers3

2

You can either not create a copy of the array itself because that changes the reference to the old array and hence any operations on the new array would have no result on the old / passed array.

Or

If you want to limit the operations in the child component and want to send the data only after click of a button, like say 'Save' button, then you may use @Output property to send the array in your child component to the parent component. The @Output works just like emitting events.

Ankit Sharma
  • 1,674
  • 8
  • 11
  • The first option is my choice. But I have to pass a new instance, else it is not recognized by changedetection @Ankit Sharma – Max Jul 05 '18 at 07:49
  • @MeMeMax Change detection doesn't work? can you reproduce it in a stackblitz? Seems to work fine here: https://stackblitz.com/edit/angular-qsgbw3?file=src/app/picklist/picklist.component.ts – cyberpirate92 Jul 05 '18 at 08:00
  • @cyberpirate92 thanks for your comment. I found that it´s due to the list component, which I use. I used
      only for demo purposes. In my real application I use ag-grid https://stackblitz.com/edit/angular-qsgbw3
    – Max Jul 05 '18 at 08:26
  • Sorry this is the correct stackblitz for my comment: https://stackblitz.com/edit/angular-jfunyh – Max Jul 05 '18 at 09:05
0

why you don't just use services for this

1- create new service and add it in app.module.ts

2- in service file add your array and add a method that when it fire update the array by push new value to it.

3- you can access to this service in both components whether retrieve the array or push new value to it

4- both components will get the same instance of the service which is the same array

Amir Fawzy
  • 468
  • 5
  • 12
0

The problem: You are mutating an array in the child component and the grids aren't getting notified of the changes, the grid seems to be checking ONLY for reference changes. (Check this answer for a similar problem)

You have two options

Option 1 - Use a EventEmitter to notify parent of changes

Emit an event when the data changes.

@Output()
onDataChanged: EventEmitter<any> = new EventEmitter();

moveToTarget() {
    this.targetList.push(this.sourceList.splice(0, 1)[0]);
    console.log('this.targetList');
    console.log(this.targetList);
    console.log('this.sourceList');
    console.log(this.sourceList);
    this.onDataChanged.emit();   // <---
}

Then in the parent component, refresh the array upon receiving the event

<app-picklist [sourceList]="sourceFunction" [targetList]="targetFunction" 
(onDataChanged)="refresh()"></app-picklist>

public refresh() {
    this.sourceFunction = [...this.sourceFunction];
    this.targetFunction = [...this.targetFunction];
}

Stackblitz

Option 2 - Create a shared data service and make use of Observable/BehaviorSubject.

cyberpirate92
  • 3,076
  • 4
  • 28
  • 46