Search code examples
angulariso8601

Calling toISOString() thows "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked."


I have this method here in a component:

getTime(): Date {
  const date = new Date();
  date.setHours(this.hour);
  date.setMinutes(this.minute);
  date.setSeconds(0);
  return date;
}

which I call within another:

<input matInput [hidden]="true" formControlName="time"
           [ngModel]="this.timePicker.getTime().toISOString()"/>

However, even though the string gets correctly generated (at least that's how the JSON looks like):

"time": "2017-11-14T10:30:00.271Z"

I'm getting this error:

CreateGroupComponent.html:40 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '2017-11-14T10:30:00.338Z'. Current value: '2017-11-14T10:30:00.341Z'.
    at viewDebugError (core.js:9514)
    at expressionChangedAfterItHasBeenCheckedError (core.js:9492)
    at checkBindingNoChanges (core.js:9661)
    at checkNoChangesNodeInline (core.js:13674)
    at checkNoChangesNode (core.js:13646)
    at debugCheckNoChangesNode (

I see this error only if I call toISOString(). If I just return the Date object it's fine but converting it to an ISO string gives me that exception. Why?


Talking about toISOString() - where's actually the timezone information in

2017-11-14T10:30:00.271Z

? For me, it's actually supposed to be

2017-11-14T10:30:00.271Z+01:00

Solution

  • This happens because milliseconds change on each getTime call, this is what the error says.

    It should be:

    getTime(): Date {
      const date = new Date();
      date.setHours(this.hour);
      date.setMinutes(this.minute);
      date.setSeconds(0);
      date.setMilliseconds(0);  
      return date;
    }
    

    Regarding timezone, the reference states,

    The toISOString() method returns a string in simplified extended ISO format (ISO 8601) <...>. The timezone is always zero UTC offset, as denoted by the suffix "Z".

    If local time is expected, see this question for possible solutions.