How to force UI update in a Angular function

Viewed 21

i have been strungling to find the right way to do a really basic thing in angular.

Most of the time it's when i want to display a loader when something takes time, i have a isLoading variable that i switch to true on the start of the function and to false at the end.

In between those i usually have a for loop that takes time because of the amount of data ( i can't change that ) the variable do change in the browser's console but not in the UI.

I've made a basic setup on stackblitz to show what is happening

When you click on the button the square should turn red while the loop is still looping because of the ngifs, but nothing happens on the UI.

I used to use a setTimeout but is there a good practise for how to do this ? Or am i doing something wrong here?

1 Answers

Your stackblitz is not really representative for 2 reasons :

1 - 1000 iterations are peanuts for most computers. The operations are finished way before you can see the color change.

2 - a loop is thread blocking, so the UI can't update while the loop is running.

If you take this into account and use a setTimeout call, you will see that it works as expected.

Example demo

Other than that, to answer you, you can detect the changes for the UI manually with the private function in the demo.

But know that there a A LOT of other solutions (for instance, setTimeout is one of them), all thanks to ZoneJS. I could go for days about it so I'll not do this, but I invite you to take a look at what is zoneJS, and how Angular uses it !

EDIT : to clarify point 2

What happens when a thread is blocked in the way you demonstrated it, is this :

  • the boolean is changed
  • the loop runs
  • the boolean is changed
  • the function ends
  • Angular updates the UI

You can see why this is problematic. But if you use a timeout, which is non-blocking, this happens :

  • The boolean is changed
  • The timeout is queued
  • The function ends
  • Angular updates the UI
  • 2 seconds passes
  • The timeout is processed
  • The timeout ends
  • The UI is updated

See, now you have two updates, hence the issue with a blocking operation !

Related