0

I have an ngFor cycle which goes through an object I get from the server. Everything works well like this.

<tr *ngFor="let item of clientPositions"> 
    <td ">{{setStatus(item.exitPrice)}}</td>     
</tr>

The component part just looks if there is a number coming in:

setStatus(exitPrice) : any{

    if (exitPrice>0)
      return "closed";

      return "open";
}

Pretty simple, if there was an exit price I assume the position was closed and I return closed as status.

Anyway, I want to color up the closed or open values so I add this.

<tr *ngFor="let item of clientPositions"> 

      <td #status [class.openPos]="isPosOpen(status)"
              {{setStatus(item.exitPrice)}}
      </td>         
</tr>

And a simple methis in the component to return true or false:

isPosOpen(status) {

let val = (status.innerText);
if (val==="open"){
  return true;
}

return false;
}

Here I start having problems... First of all it is this error:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.

I tried debuggin the isPosOpen(status) method in the console and it seems the cycle is spinned numerous times. Twice at least and I have no idea why angular does that. Probably that is where the error occurs. The data is received OnInit like this:

ngOnInit() {

if (this.auth.isEmailVerified){
  this.service.getPositions().
  subscribe(positions => {
    this.clientPositions=positions

  });
}
else{
  new NotVerifiedError(this.toast);
}
}

So far I'm pretty stuck with this issue. Will be really gratefull for any suggestions.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Yuri Zolotarev
  • 721
  • 9
  • 23
  • Instead of using isPosOpen(status), why not using setStatus(item.exitPrice) === 'open'? – jlareau Aug 25 '17 at 14:35
  • I would suggest read this answer , you will get some hints about this issue https://stackoverflow.com/questions/45467881/expressionchangedafterithasbeencheckederror-expression-has-changed-after-it-was – Jameel Moideen Aug 25 '17 at 14:42
  • I think the error occurs because you reference the template (`td`) to the method of that template attribute (`[class.openPos]`), this also happened to me last week – samAlvin Aug 25 '17 at 14:42
  • this error will go in production mode – Jameel Moideen Aug 25 '17 at 14:44

1 Answers1

0

It seems like your getting this error because you're passing in a DOM node which is created by angular and due to it's creation angular tries to invoke the method to apply the class. Which leads to a different outcome during double changeDetection in development mode.

You could just implement your isPosOpen open method like this:

isPosOpen(item: any) {
  return item && item.exitPrice === 0;
}

And use it like this:

[class.openPos]="isPosOpen(item)"
cyr_x
  • 13,987
  • 2
  • 32
  • 46
  • Thank you, I forgot you can pass an item in the method paramaeters, I was tryeing to pass it like this {{itme.exitPrice}} and was getting errors but as soon as I read your answer it became quite clear that it is the DOM change detection algorithm which is bugging this situation so I just passed [class.openPos]="isPosOpen(item)" and now I can do whatever I want with it. Thank you. – Yuri Zolotarev Aug 28 '17 at 05:28