2
votes

Short story:, I am getting an error Expression has changed after it was checked. Previous value: 'xx'. Current value: 'xx'. when I update a variable from my component.

Long story: I have a ParentComponent that contains the variable I am updating named totalAmount. Then I have a ChildComponent which affects the value of totalAmount but doesn't have access to the said variable. What happens is I have a subtotal variable in my ParentComponent which I pass to ChildComponent using @Input then I just recalculate the totalAmount from the ParentComponent since I have access to subtotal in it. Just like this:

ParentComponent.ts

this.totalAmount = this.subtotal + (some other values)

Then I display it on my ParentComponentTemplate.html like this:

<span>{{ totalAmount | money }}</span>

And it all works fine. Then suddenly the totalAmount had to be in an input box because there should be a way that it can be overriden. So instead of a span element I had to do it like this:

<input type="text" name="totalAmount" [(ngModel)]="totalAmount" />

Now that's when the problem starts. Everytime the subtotal in my ChildComponent changes, I get the error Expression has changed after it was checked. Previous value: 'xx'. Current value: 'xx'.

Now I've read several articles about this already that it is a feature in Angular but how do we go about this? Is there a solution to this instead of a workaround?

Thanks in advance!

2
Can you show us the child component? - Християн Христов
Could you provide the two classes / components? You would need to refactor your code into a unidirectional dataflow. The flow would be correct with an EventEmitter or a service, where you subscribe to the change and then you will update the value, instead updating the value directly. - Stefan Rein
<input type="text" name="totalAmount" [(ngModel)]="amountDue" /> i hope this is typo you should bind textbox with totalAmount ... - Pranay Rana
added my answer can help you out - Pranay Rana

2 Answers

2
votes

The solution is that you must understand the error and change your code accordingly.

Although pretty explicit, this error doesn't state that it is a lifecycle error.

If you want to resolve that, you will need to follow the lifecycle, instead of trying and see what happens.

And although you seem to believe you posted enough code, you didn't : next time post your whole code instead of an explanation, because even though it seems clear to you, it isn't for me.

Finally, javascript variables are passed by reference : this means that when you change the value of an input, you change the reference, not the value.

So, what you could try :

  • the parent has the total amount
  • the child doesn't have any @Input
  • when the value of the <input> changes in the child, you emit an event
  • the parent listens to that event, and changes the total value accordingly
2
votes

Now that's when the problem starts. Everytime the subtotal in my ChildComponent changes, I get the error Expression has changed after it was checked. Previous value: 'xx'. Current value: 'xx'.


Error is coming when you are chaning subtotal in your child component.

And you are using subtotal in you parent component here

ParentComponent.ts

this.totalAmount = this.subtotal + (some other values)

that is causing problem.


Solution might help you is do code like this


in childcomponent.ts

Promise.resolve(null).then(() => this.parent.subtotal = calculatesubtotal );

Have look : Everything you need to know about the ExpressionChangedAfterItHasBeenCheckedError error