Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
September 28, 2022 03:39 pm GMT

Its ok to use function calls in Angular templates!

You should never use function calls on Angular templates! Thats what you will see all over the internet! And Im here to prove to you that thats not always the case!

The issue

Every time Angular change detection runs (from events, setTimeout, manual or anything else), everything on the template will run again with it, thats also the case for function calls. Why does Angular do this? Because it needs to check whats changed on the template in order to update it.

If the function does something heavy, it will impact the performance of the application, because the way Angular updates the view is synchronous, and it will have to wait for the function to finish and then update the view.

The Use a pipe solution

The solution well mostly see is Use a pipe. This is recommended because the pipes in Angular templates are more performant. How so? Because Angular will re-run the transform method of the pipe only if the parameters we pass to it have changed.

Lets prove it!

Lets dig in the source code

In the new Angular compiler (Ivy), templates are compiled into instructions. Lets take an example and see what it generates.

Heres a component with a simple pipe.

And heres the cleaned up generated code:

As we can see, in line 29, thats where we see what Angular generates for the template code.

So, there are instructions for creating a div, adding text, adding a pipe, closing the div, creating a button and adding a listener to it (Ivys cool stuff ). We can also see the if/else statement. What it does is, it separates the view creation from view updating, the first if does the view creation and the second one is for the updating part. You can read more on that here.

We are interested for the line 33 and 43, because thats where the pipe does the magic . In line 33 it registers the pipe in the template and the binding of the data happens in *line 43 *(in the update phase). We see that it interpolates some text and that text comes from **pipeBind1() **function. Lets see what that function does underneath .

Link to source code [here](https://github.com/angular/angular/blob/main/packages/core/src/render3/pipe.ts#L123)

As we can see, the first three lines get the information for the pipe instance and then we have a return statement. In the return we have a check for isPure(), and it just checks if we have set pure field true or false in the pipe decorator.

If we have set the pure field to false it will directly return the pipeInstance.transform(v1) value, meaning Angular wont do anything special with the pipe but just run the transform method again. It would be the same as using a method from the component class.

If the pipe is pure (as in our case), it will call the pureFunction1Internal helper function** and will pass some fields to it. Lets see what pureFunction1Internal does underneath.

Link to source code [here](https://github.com/angular/angular/blob/main/packages/core/src/render3/pure_function.ts#L307)

We can see that it checks if the binding is updated in the bindingUpdated function, and if thats true it will update the binding otherwise it will return the value of the pure function (the current value). Lets see what check it does underneath .

Link to source code [here](https://github.com/angular/angular/blob/main/packages/core/src/render3/bindings.ts#L46)

So, what it really checks is if the old value is the same as the new value (using Object.is()). You will ask: what value is this? Nothing else than the parameter that we have passed to the pipe transform method.

It means that if none of the parameters of that method has changed, were good to go, we can return false and we wont have to run the function again, we can just use the old value of the binding.

And thats what we wanted to prove in the first place .

What does this mean for us?

It means that we can create a helper function that does the magic Angular does for us, without needing to use a pipe at all .

Heres the helper function, well explain how it works below.

So, memo is a function that accepts a function as parameter and returns a result.

In line 6 we check if the function parameters have changed, thats what hasDifferentArgs function helps with. It first checks if the length of the args has changed, if yes returns true, and then does an equality check (just like Angular does with pipes) of the parameters.

If the parameters have changed we call the function again with the new parameters and save its result, and if not, we return the old value.

How to use it?

Heres the example above converted to use the memo function.

Just like that! And yes, we are using a function in the template! And yes, its not a problem doing so!

The idea and the inspiration for the blog post?

All thanks to a tweet from Pawel Kozlowski, an Angular team member. I just thought to dig more on the source code and explain it further.

Youre interested in reactivity, signals, performance, change detection an other cool stuff like that? Go give Pawel a follow on Twitter, he is exploring the space and tweeting cool stuff about it!

While youre on Twitter, give me a follow too at @Enea_Jahollari if want the** latest Angular news*, **videos, **podcasts, **updates, **RFCs, **pull requests* and so much more. Give me a follow on dev.to if you liked this article and want to see more like this!

Thank you for reading!


Original Link: https://dev.to/eneajaho/its-ok-to-use-function-calls-in-angular-templates-4029

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To