2

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?

5
  • 4
    pls console.log(this.arrayB) at last in doSomething func and see if there are actually any differences Commented Jul 5, 2017 at 13:15
  • 1
    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. Commented Jul 5, 2017 at 13:47
  • @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'. Commented Jul 5, 2017 at 15:39
  • @Dhyey I was wrong. Without the 'conditions', it still fires twice. Commented Jul 5, 2017 at 15:43
  • @RolandRácz can u pls reproduce it in a plnkr and post the link ? Commented Jul 6, 2017 at 6:06

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer. It turns out that the filter is fine, but the doSomething() fires twice (even if I clicked only once). The first time, the arrayB is right, but the second time it's the original. The question is, why is this behavior.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.