1
votes

I have a component with two array. arrayA and arrayB. arrayB contains filtered elements of arrayA. And in the template:

<div *ngFor="let elem of arrayB">{{elem.something}}</div>

I have a button too:

<button (click)="doSomething()">Do Something</button>

In the doSomething method I use the filter method on arrayA to update arrayB.

doSomething() {
    this.arrayB = this.arrayA.filter(elem => { return ***some code***; });
}

The problem is that the view doesn't refresh. I tried to use NgZone (ngZone.run(): I wrapped the code in the method.) and ChangeDetectorRef (detectChanges()/markForCheck(): I called this at the end of the method.) too.

What should be the solution for this?

2
pls console.log(this.arrayB) at last in doSomething func and see if there are actually any differencesDhyey
You shouldn't have to mark anything as changed if the button click event happens inside the same template as the ngFor. You only have to tell Angular it's changed if it's outside the change tree or changed after it's been checked. Maybe the problem is that arrayB hasn't changed when you thought it should.Reactgular
@Dhyey After I checked the array with console.log(arrayB), I noticed a strange thing: the doSomething() fires twice. The first time, the arrayB is right (filtered), but the second time... it's the original. My (click) looks like this: (click)="foo && !foo.bar && doSomething()". So I guess the problems are these 'conditions'.Roland Rácz
@Dhyey I was wrong. Without the 'conditions', it still fires twice.Roland Rácz
@RolandRácz can u pls reproduce it in a plnkr and post the link ?Dhyey

2 Answers

1
votes

It should works ! make sure that your filter is working, please check this example:

<div *ngFor="let elemB of arrayB">{{elemB}}</div>
<strong>array A :</strong>
<div *ngFor="let elemA of arrayA">{{elemA}}</div>
<button (click)="doSomething()">Do Something</button>

TS :

 arrayA = [0,1,2,3,4];
 arrayB = [];

 doSomething(){ 
     this.arrayB = this.arrayA.filter(x => { return x > 2; });
 }

https://plnkr.co/edit/VQYoVIGoioPwjW1ThcFQ?p=preview

0
votes

In the doSomething() method I returned with true. Because of this, the method fired twice. So the solution is to always return with false.