Video details

Dependency Injection Patterns | Angular

Angular
06.03.2020
English

Nir Kaufman

NG-Poland's Angular Online Event #5 Nir Kaufman - SOLID Angular with Dependency injection techniques Minko Gechev - Q&A Here are links that Minko promised during the session: 🚀 Getting started resources on performance https://web.dev/en/angular 🚀 Lots of folks seems to be finding this (https://www.youtube.com/watch?v=ybNj-...) talk useful for runtime performance 🚀 More (https://bit.ly/3gM9prL) on OnPush change detection 🚀 Optimizations with pure pipes and memoization here (https://bit.ly/3cvoHxA)

Transcript

The wrong link. Mm hmm. I can see number four, I can't find number five. It's the same link. Oh, it's the same link. Yeah. You just detect the title, say Anger online, event number four and sign number five. It's this. Oh, you want a second, detective? I don't say I'm going to. Online again at number four. Yeah. It's this. This weekend, can you send me a link? Yeah. This is. Can you send me a link? Yeah. One second. Mm hmm. Mm hmm. Make sure you hear me through Zuman. Yeah, like I can hear you. So it won't be any delay. Yeah. Online. So I'm look, I'm just looking for the link. Yeah. And they can find it. Uh. And. You can send it on. What's up? Dustin. OK, OK, fellow, we are on line. We've near. Mir. Can you hear me? Can you see me? I can hear. OK. Perfect. So let's start the fifth event. And a lot online event today, we have two special guests. First is the new Kalif mom, we've dependency injection. And second, a segment called Get Tough and Mean. We've Minko. We have our Q&A session. So. Please write in the chart, you can hurt us. You can see us and we can start the meetup. A. Hello. Hello. Hey, Minka. No Minko. Hey, where are you? Thank you. Nice to see you guys. Okay, so now once again, we can start the next Angler online meet up near Cole's mom. Your first saw your. The stage is yours. Have fun. Thank you, Derek. Today, we're going to continue a serious there. I recently started, which is the angular martial arts serious. If you haven't seen it before, you can search YouTube. You can see one of my students dressed as a ninja. Today, I decided to come and talk about deadly dependency injection patterns. It's not deadly in means of it can risk your life, obviously, but it is deadly because if you must take this technique, you can do stuff that make the quote sheever. This is called Duquan D. And let's get started. So I prepared this tiny demo app, which basically doesn't do to watch. But if I click this button, I'm gonna make an API call, which is going to result in the 200. Hopefully you can see it. Let me make it a little bit larger. And I can generate a four or four. And I can generate a fire hungry request. And here it's a button. It doesn't do anything. So this is our stage for today. I want to share with you a dependency injection technique that I use a lot that enable me basically to implement a feel for the ideas that I've taking from the solid principle. If you're familiar with the solid principle is one of the I think, the most popular object oriented design principle. I don't want to get too much deep into the theory because I believe of keeping everything practical. So let me just start Cody, again, explaining what I'm trying to achieve. And at the end of this demo, I feel connected to the actual solid principles. So that's the code. Currently, I've got only one component, the app component, which, like I said, doesn't do too much. I've got few buttons. Each one of them using this tiny library, making an API request and getting status back. I'm using this HTP stat, which is a great website if you want to test different responses from the server. Anyway, the feature that I'm going to implement from scratch is gonna be some kind of an air central alert or messages feature, which basically can catch arrows through an interceptor or just show general UI messages that you might want to display from time to time. And like always, I'm gonna start with creating a new angle module. Let's call this. Messages. Or you know what alerts? And there is a good reason, because a lot of people asking what are the reason to create a separate module in Angola, specifically those things with Ambuhl are nine, that for some use cases we can make the model. But for me, Angela modules, it's much more than just, you know, a dependency injection container. It's a way to organize my code in in this specific way that I find very useful. And hopefully, by the end of this demo, you will totally understand why I decided to take this tiny feature and create a dedicated model for it. So I created this alert module on a separate folder. And the way that I like to work with Angular recently I Cam came up with this. Term out of nowhere, which is the provider oriented development, just the way that I like to teach, especially new developers, have started to use the framework, which basically means that when I try to implement a feature, I'm always it by creating a service provider, a simple class, the tools, the logic, and then use other Anglo component in order to consume this logic and connected this logic to different parts of my application. It can be a component. It can be a guard. It can be a pipe. It can be an intercept. All I can this example. But everything starts for me with creating a provider which holds the logic. So I'm gonna call this provider alert. And because I'm using the angler's selye, I'm gonna get the suffix alert service. Make it a little bit larger. And on this alert service, I'm going to create a few private properties. One of them going to be messages or you know what, let's just call it alerts. Which is going to be. And behavior subject. It's going to contain an array of alerts. I learned, which I haven't defined yet. I can create an interface. We'll fast, let's say that alleged quantity. Just got some text. So that's going to be a private behavior subject. I'm going to create a private alerts. Q. Just gonna be an empty array. And let's just see how they just change it. Let's call this an alert. Q. And finally, I'm going to expose the Read-Only. Alerts observable. Which is going to resolving to alert. Laird, right? So I decided to start by live, calling this part of the service, because it's kind of a common pattern recently to create a service which use behavior subject and expose a read only observable, which is like you're going to see in a second. Gonna be taking this behavior subject and exposed it as an observable. And these techniques enable me very easily. Let me paste them code here and change the naming. That's gonna be this. Alerts. Q. This. Alerts they behavior subject. And these alerts. Which is. They behave a subject. As an observable. This why I don't expose the behavior subject. I'm just exposing this alert observable where I can omit events and connected to my reactive you I. This service going to contain. For now, let justice implement just one method which is set alert. Which is going to take an alert. It's an argument. And the only thing that I'm gonna do, I'm gonna take this alert. Push it into my. Alert. Cue. And then I'm going to call alerts. Behavior, Exell Bull, next. Sending away. This. Alert. Que. So this matter is going to take an alert. I'm going to maintain my own internal array, which is not that important for this example, but is a nice button that got some very good reasons behind it. And I'm going to share later on. And this is the most important line I'm pushing. I'm calling next on the behavior subject. I'm pushing this alert cue this new alert you with this new alert unit, which is exposed as an observable. So now we can create. A component, it can consume it. So I'm done with the service. I've got the provider in place and I can start go go on and connect this service to different angular components. And when I say components is not just mean and not just mean like UI components, it can be, like I said before, interceptors or other services. In my use case, I will start with the components. So I'm gonna create an angular component. Again, I'm using the same name. Alert. So now I've got an alert component to it. You can see right here. And this alert component we're going to do something very simple is a starter and you container. And EUFOR. And for every alert off alerts, which is, I think. When are we going to do now? I'm just gonna use bootstrap. To create a nice alert. Alert to danger. And right here. Let's take the alert text. And show it. Remember here I've got an interface called Alert and I've got text. Next, this component. Gonna inject. Our alert service. And. Gonna expose alerts observable from the service. Actually, I don't even need to do this. I can just do alert service alerts. Let's do this public and. It got everything in place. So this tiny reactive component doing something very, very, very simple, injecting the alert service where all of our logic is implemented, assigning an alert observable from the service. Some people like to inject the service and and bind it directly to the template. I don't like to do it for a lot of reasons. I like to keep all of my injection private and just exposed to the template wherever I want to expose. And usually integrated with the component lifecycle methods. So I won't get into a situation where my alert, where my provider, my service provider, updating a value on the template and I'm getting some kind of a race condition or the famous value was change after the components was checked. So this component is gonna take this player from the series and it's going to run with an energy for and show those alerts. But that's not enough. I also want to be able to create or set alerts within different places in my app. So for this model, I'm going to create an interceptor. Let's call this interceptor API error. My interceptor. Exactly like the. Alert component gonna inject the alert service. Because everything is around the provider. That's the reason I'm always start with the provider implementing the logic. And then, like I said, connected two different different components in the framework. So this interceptor, I wanted to catch API arrows and use this alert service in order to display an alert. So what I'm gonna do. When a paste some code, because I know I don't want to waste too much time. On the implementation where I'm going to go. Step by step and show you exactly what's going on here. And let me just import everything I need. All right, so this interceptor going to intercept all the HTP requests. Let me just. Get rid of this. Thank you, Rick. But it's actually a request, but I care about the response. So this is a very common implementation of calling. Next, calling the request and then type a catch error. So if something went wrong with Y API request, I can catch an error and use the alert service in order to set an alert and push this object. Again, let's not focus about the actual implementation, because that's not the important part of this demo. Obviously, you can write. I'm sure you can come up with a better implementation of how you can catch specific areas so you can handle different kind of errors. Same for the service itself. But if I go back to the to the concept so we started with a provider because everything is around the provider. This is the provider oriented, angular approach. I started with creating this provider, which contains the logic and then a component that consume this provider and use it in order to display the alerts. And then an interceptor that consume this provider and used the set alert method in order to push a new alert and everything back together nicely inside this module. So currently this module is declared the alert component. Which I'm going to export, I'm going to register my alert service. Right here. And I think we kind of okay with this. We can try to use our. Oh, wait a second. I forgot to register the interceptor. So let me come here to my provider's. And use the HTP interceptors. Injection Dorkin. And is this class, which is our API error interceptor. Not forgetting to mention that this is a multi injector, we gonna write one of these by our own in a second. So let's look off of what we did up until now. We've got a nice module that pack together, a provider, a component, an interceptor. And I can go back to my F module. And that's the nice thing about Angular, that that's all I need to do right now. Hopefully, unless I miss something, is take my alert module. And if I want to use the component, I'm going to use my alert component as part of my bootstrap component, because what I want to do when I go to my index, H.D. mail, and I want to use it right here. And that's right away. That's the question that I get a lot, because in a lot of my demos, I am creating more than one bootstrap component. And sometimes I get these questions, why? And what's the benefits of this? Well, this is a plain aged e-mail file. Actually, you can write here a bunch of static markup that's going to be rendered right away. They're part of where angular starting to use JavaScript to render the contents happens within this element. They're approved. So it's totally okay to create more than one bootstrap component if you want to render another route in your index, H.D., m.. And it's totally okay to add some extra H.D. mail here if you want to get something shown on the screen until ANGULAR is loading. You can also put some content here, like clothing, which are going to disappear once Angular started to run. So a lot of times we use this to get a better user experience without too much effort, just creating a lot of static markup and let Angular render whatever he needs. So I put my ankle and K alert right here beside the approved. In the future, I might add, some see says and I want to align it against the body, but that's not the point. Let's go back to our app component. And right, you see, if we can get something going back to the browser, I'm going to try to generate a 500. And we get a nice alert right here. So that was the basic. Up until now, everything looks good and everything works as expected. And we kind of get the full experience of Angela, how we can use dependency injection and features like interceptors and reactive components wrapped in the module. And all we need to do is just drop this module into our app module and get this feature done. Obviously, if I just remove it, I'm using this component. I'm not rendering it dynamically. So we'll get an error. But I've got everything nice, packed and isolated inside this module so we can stop right here. But now I want to show you how I implement a principle called the Open Close Principle, which I took from this solid principles. And like I told you, I won't get into theory at all. I'm going to implement the feature, explain the motivation, and then connected to the theory. Generally speaking, I would like to be able to add some custom logic or to extend the behavior of what's going on inside this module, but without touching the source code of this module. In other words, I want to create some kind of a mechanism which enables me to add logic to the model without touching it. Every model should be able to be open for extension, but close for modification. That's I think, if I remember right, the definition of this principle. So what I'm gonna do right now, I'm going to go back to my alert module and I'm going to create an injection talking. I'm gonna to call this stock an alert. Logger's, I'm going to use the on U injection. Tolkan. And this injection took let's. Yeah. You know what? For now, I'm going to say any array, but I've got to change it in the seconds. So don't worry. I'm just. I don't even need to do something here. But. Let's leave it like it's a. for a second. I'm gonna call it in a little bit longer. Now, I've got an injection talking that I can work with. What's the point behind it? Well, let me take it to separate from what what I was intended to do anyway. I'm gonna create another file. I'm going to create a call. This file alert. Type's. Because I can think of something better right now. It's gonna contain dystopian. And remember, did I tell you that I'm going to replace this any I want this injection token to contain? To be binded to a specific interface, it's easier to me to explain with code and then explain with war words. So I'm going to create an interface called Alert Logger. And this interface, the alert clogger, going to have only one method, which is Lugg. It's going to take. Whatever, let's say. It's gonna take an alert because we've got a we've got an interface for this. So we're gonna take an alert. I am not going to return anything. So this injection token going to be an array of anything that can that will implement the alert, Lowgar. But up until now, we didn't wrote any logic at all, which is part of the idea that I'm trying to show you, which is let's create interfaces, let's create abstract injection Tolkin. Let's not deal with implementation until we're gonna have to do it. So let's talk a little bit about this injection token. Remember that when you when I created the interceptor and you're seeing this all around, I register my interceptor under a built in injection took and it came from Angola called HTP Interceptor. So in a way, I was able to add my own logic into something that it's built in inside of ANGULAR. And this is exactly what I'm trying to achieve right now. Just like I was able to add my own interceptor and ad run this logic as part of a black box and a model that came from Anguilla without the need to go into the source code or change something or hack something. I want to use this this message, this alert, a Lowgar multi injection to do basically the same thing. So I'm gonna go back to my service and I'm gonna use dependency injection. But now I'm gonna inject. My alert logger's multi injector. I'm going to market is optional. Because I don't want it to crash if it's not if it's not available. And that's hopefully going to give me an array of message loggers. So that's gonna be an alert. Lariat. Where is where is my alert logger? Let's go type. And don't forget to export stuff because otherwise you can't reach it from nowhere. So that's gonna be a little bit longer. Array. All right. And again, look carefully. Now I've got a service component. Whatever a piece of code where I inject something that is not first is not yet exist. And one of the reasons that I make this optional is because I want it to be optional. Second, it's 100 percent abstract. It's going to is using a token just to talk. And it doesn't have any implementation associated with it yet. And I define the type as an array of an interface. So it's again, it's not a concrete implementation yet, but because everything is binded to an interface and I've got a dependency injection mechanism. Now I can go ahead and I can write some log, for example, every time you set an alert. I can go ahead and check if this logger's. It's supposed to be in a. So let's do something simple. Because sometimes the most simple form of code, it's the best code that you can write. I done recently, I started to to take a step back from writing what I call, like, fancy JavaScript and try to be as simple as possible. So if it's if I'm expecting to get an array of floggers, I can check if this thing is now. And I can also check if the length if and if I've got logger's and if the length is more than one, it means that I've got. An array of floggers, and if you've got an array of floggers, I can loop over them. And for each one of the longer. I'm just gonna call Lowgar that Lugg. And I'm going to stop right here. We've got like few minutes to complete this demo, specifically this Istanbul, and talk about it. But let's go through the code. We'll quick. So the first step was to create an injection token. It's just a token. There is no implementation is something that I can work with that I can register. Use it as a key to register my own logic. I created an injection, took an invalid injection, took and that's the reason I use the new injection. And you can't use whatever you want, you can just declare it Constanten and hope that it's going to work. Next, I defined an interface. If you're going to write your own logic, your own logger's. You have to two. You have to obey to this interface because. When I implemented my own logic, my internal logic, this alert service, I gave you the option. Two extended wait logging capability. But I rely on a specific interface. So now. You can write your own logger's under this key and my code. Going to accept those logger's to be of type a letter clogger and every time someone set an alert. I can run. And use this logger service all around. Let's see how we can actually make it work. So the nice thing about it now is that if I did everything okay, I can go to my F module. And without touching the alert module, I want to try to to add my own custom logging functionality to this alert module. For this, I'm going to create an array of providers. And I'm going to use this injection talking that I created before, which is alert logger's. I'm going to add my own implementation. Let me create a class call on call Lowgar or just you know what? Let's make it crystal clear. Custom. Lugger. I've got a feeling off with type all. And I'm going to implement the alert. Come on. The alert logger interface. Now I have to implement my log, which are going to get an alert. And let's bring something back from the 90s and do a real alert. I don't think that's gonna work. I'm just gonna get guns to lug my costume. Lowgar. I'm consistent with my typos, which is good consistency. It's very important. Alert. Text, so here I've got my own logic that I created within the app module contents context. And within the app module, I'm using this key that was provided from the alert model, which enabled me right now to assign my own logic. I'm using the Malti true because I want to make sure that I can add some extra Lowgar to this multi provider. And let's give it a let's give it a try. Let's see what's what's going to happen. So let's generate forward for. And almost. I think it did something bad. Because I can see my log. So let me check real quick. Where it messed up. So I've got to alert loggers. I've got my mccastle logger. I've got it Malti true. I think it just a matter of. Give it at the nice real refresh. That's if I right now. So I've got my alert logger's, which I provide right here in providers. I've got my alert module. I can go ahead to my alert module and check my service, my alert service, and let's see what's up here. I'm injecting the alert logger's of that, an array of floggers, hopefully, and if the length and I've got it in is more than one. Let's do a quick debugger here. And don't worry if that's not gonna work, I'm not gonna waste your time. We're gonna see. A working damn, why did I prepare ahead for those kind of situations? And here's the debugger and DS slugger's is undefined. I was unable to fulfill my promise and show you a working example, but I'm gonna dedicate like five seconds to it if that's not going work. I'm gonna launch the demo with a rapper as a backup. Before the talk, let's see why inject alert logger's, which is optional. Private slugger's. And let's go to the alert. Module. And see if I did anything wrong here. But it seems like this. The last thing I'm gonna do, you just make sure that I don't have any local. Out of sync environment. Meanwhile, I'm going to go back to my EP module. I'm going to check it again, provided some providing the alert, Lowgar, I'm using this class custom logger right here. We've got the log in using a multi true. And less. Before we do. Oh, sorry. That wasn't my intention. That was me accidentally stopped sharing my screen. Let me try to generate a four for I hit the debugger again and our logger's are. And define right. So doing the same mistake again and again and again. So unfortunately, I wasn't able to show you that example working in lifeguarding, but that's part of lifeguarding. So let me quickly go back to the code. And let's close this project. And I'm going to open up. The backup demo that I prepared just before they made up in case that lifeguarding goes wrong and I go back to my workshops. To the angle that martial arts. To do this project. Let's go with this window. And let me quickly do an end, you serve to the Q&A. It's the second condition of the luggers should be lenth oh. Yes. Huh? You're smarter than me, that's for sure. Yeah. Let's go back to the duck one day. Someone actually catch my mistake and. And let's let's fix it appears that they just missed something very, very important. You see this condition. If this logger's length is more than one. Don't do anything. Well, we've got one longer. So it should be more than zero. So now, hopefully. If you go back to the project. Where are we? Here we are. Let's refresh. Let's open up the console. Let's try to generate an error and see what's going to happen. Debugger, these loggers are still undefined. So. And naturally, twice the problem. I probably missed something. So let me go back to working Danielle and we summarize and end up this session. So Angela conc view. And we got to. And you serve. One day. This is a walking example, there are people for you in order to share it and get up. So you can see hereunder up here, I didn't call it an alert. Call it a central message. But the concept is the same concept you see right here that I can create my own custom logger's message luggers and using this multi provider key in order to add my functionality and extend the central message module, which internally. Internally. Got a service. Which. Where are you? It's the right one, which intentionally got a service that inject the loggers exactly the same, coded that road right now with you, just messed up with something. And the same conditions apply right here, if the lengthy zero go ahead and call the slugger's, let's check it out. Cool. So I'm going to generate a four for. That's not my lucky day. I can tell you this. Sometimes you've got everything working and sometimes you don't. Actually, I know I know exactly what's going on here because this demo took this this whole thing like a step a step forward. So there is there is another service here. That config, this entire thing. Do not plug. So let me fix it, because I don't want to let it go before you can see it actually working, because otherwise you're not gonna believe me. So a central message, the message service that I created. Configuration. I'm gonna remove this piece of code right here. Leaving it just like I show you when you set message. You go over the loggers and for each logger, you log a message. And finally, finally, finally, hopefully, let's generate a forum for. And Heagle. So let me summarize all for the Life demo. Wasn't like a wow show. That's the thing when we build modules like the central message models, and if we like to be able, we consider to be a good practice, which actually considered to be one of the most famous best practices, because it's one of the those solid principle, the open, close principle when we design a module. Or or every piece of code, but specifically and I will a module and we like to write our code in a way that enable us to add custom logic and extend the behavior of the model without the need to go ahead and modify the source code using dependency, injection and Malti providers. That's the angle, a way to achieve it. Angular use the same technique all over the place. When we create validators, when we create forms, when we initialize it into the angular bootstrap process, when we build our own interceptors. The way to achieve this, though, is to create a token like this message. And then in our service, use dependency injection, inject this token. And if you edit. Any logic or any class 2D array of floggers in this example? We can. Interact with our code. With this model without touching it. So I'm going to share this entire record with you. And I'm going to answer some questions. If you've got some. And if you're going to get some more question after this session is done, because Minko gonna gonna be right here, you are more than welcome to write it in the comment and add some more some more, some more explanations. But hopefully this entire approach show you how to achieve the same behavior that we get from ANGULAR that enable us to use multi injectors or a token that can use as a as the key to register more than one class, but eventually enable us to achieve this open, close principle, which says in simple English. I can extend and add my own logic like this custom loggers into an external module without the need to modify the code of this module itself. So someone to ask is the same thing like the HTP interceptor yet? It's the same thing. It's something like the fourth module used the same thing. When you create and you form control, you register your firm control under the value, access or multi injection. In ANGULAR. We've got several places where this this multi injection become Hendee. One of them, for example, if you want to take it a step further. If you look at the example that I sent you. We've got a multi provider called AB Initializes so I can add my own coded gonna run with and we are going to initialize. So, guys, let's let me summarize. The most important thing, the one only thing that I want you to take from this example. Even if the demo was too fast, all, you know, eventually wasn't working because they probably missed something somewhere. That's not the point. The point is that when you are building your angular modules, when you're building your own logic, always keep in mind. How can I achieve? How can I implement this principle of open close? How can I ride my Anglo model in a way that will enable myself and others to add custom behavior, run at some custom logic, extend how my model behave without the need to modify the code within the model itself using dependency injection. We can achieve this kind of easily with angular. Of course we can take it, take it a step forward. But it is important to me on these sessions to focus on Malti providers and how we can actually write code that that interact with this. So I think that that's it for today, because otherwise I can go ahead and talk for hours and show you some more examples and more and more examples. I'm going to share the link to the working example in the comment of these videos. If you want to see some more, if you've got any more questions. First of all, download the get up report where you find a walking example. I added a lot of comments because I've show you not just how to use multi multi providers. This Mokey provide its features, but also how to write your entire model based on abstract classes and how to use dependency injection and write your entire feature against interfaces and not a concrete implementation. So check out the gate repoll and I'm always available. Most of you already know this is my first time in this meet up. So hit me with emails, tweak me. I'm answer everyone and I will be more than happy to extend and share some more practical techniques on this topic or anything else related to Angler. Obviously not how to grow Whitebeard. So I think that I talk too much. And now. Oh yeah. Derek Control. Okay. Here. Thank you so much. Thank you so much for this great presentation. We have a lot of made so big applause for new. And now the stage is your main call. So I've sent you a few question. We have from from some participants from last time and we can use it or and we have some question on our chart. So the stage is your near. Thank you so much. Go ahead. Thank you. We can't hear you. I was muted, okay. It should be fine. Yeah, I got a couple of I got about 20 about 18 questions already. So I hope that. You'd be curious to hear their answers as well. So in general, a group to the questions and several like a couple of different categories. One of them is relaid. It's one of the categories is related in particular to change detection and runtime performance. There is a category related to Wolesi initial all time performance. There is an HTP category and. Yeah, a couple of. Do you hear me? Let me. Yeah. OK. Zoom, Zoom disappeared for some reason. So I thought that it crashed or something. And a couple of other categories that are contained brick around, like pretty unrelated questions. It's like the utils director in a project. You never want to have it, but once in a while you do. So the first question is how to manage change detection to avoid unnecessary performance issues. There are general techniques to optimize the runtime performance of failure and your application in general or to avoid change detection. And you can avoid change station in a couple of different ways. Probably the most popular ways to use on push change detection. Now, if you imagine that the entire component, the entire application is just one large component, three where the individual components are Knesset's in one another, don't push change station analysts keep entire components up trees. So Yanguas change station is going to in general traverse each one of these components in the component three and evaluate their bindings, violate the expressions inside of their templates. So if you have very heavy bindings in any of your components or you have large amount of components which lightweight bindings, banger's change station might not be able to fit into fit into 16 milliseconds, and you may experience some performance issues you may experience like Drogo frames in your browser. So what you can do is just not perform change station when you don't have to wait on push, as I mentioned. You can skip change actually. And there are components of trees. In general, we don't push. You can say I don't want to run change picture in this particular component subtree with roots. The given component that we are applying on on on Pushtu, I want to run change station only as this component received some inputs that have different value when performed preferential check. So when we compare developers with twice, two times equal. Yeah. So I would recommend you to use on Pushtu inspection. Aside from that, you can cache some of the bindings still if you are. Re computing the same value all over again, this is probably redundant and you can save and your some time if you care. The binding somehow cause the result and directly provide it instead of re computing kids from scratch. Pure pipes can be helpful there and many other techniques. I've actually I've actually written a lot about this topic so I can share some for the resources in the chats in a bit. The second question is, how much does the binding two functions in a steel mill slow down the EP? Yeah, it depends. It depends entirely on your bindings. If in your bindings you're calculating whether a certain number is prime, for example, or not. This could be quite a heavy competition on large numbers. So this is probably going to be a slow binding. But if in your binding, you have just bound to a property and this property has a particular value that's angular, just displace in the user interface. And then this binding is very, very cheap. So if you have very cheap bindings and not too many components, very likely your application is just going to run fine. If you have large amounts of components, very like thousands of components on your page and each in each one of these components, you have very lightweight bindings. It's very likely that your application may start to struggle at certain points, especially on low end devices. So in these cases, I'll just recommend to you some push. There is a question also how to improve performance on Internet Explorer browser. It's pretty much the same as you would optimize performance on any other browser. So not too much of a difference. Maybe the Internet Explorer's Josko virtual machine is not as powerful as what you would see in. Places like Krom or like Spider Monkey and Firefox, but in general, the techniques are pretty similar. The difference are going to be mostly in past time. So probably an Internet Explorer to just be a virtual machine is going to be slightly is going to be much slower when passing your JavaScript. So this can make your initial little time worst. So in this case, you'll just have to delay some JavaScript. What, you're not immediately using the page. You can just lazy load it. And this way. Internet Explorer is not going to choke. It's a large bundle. Yeah. There is the question also, should we apply on push on everything or on some of your components? I won't in general not recommend it to use on push unless you see some performance issues. So there is this very interesting tradeoff of optimizing a little bit too early. And even if the optimization is something very tiny, something like a. Let's say your iterating over a collection of items and at certain points you break. And you don't document as well. Your colleagues might be wondering, why are you breaking in this look like? Is there anything particular what like what this condition means that you can stop iterating Corita collection? So so overall, optimizing at certain points can make your source code harder to read on. Pushes the same thing which push you're bringing some extra semantics on top of your source code. So junior developers who are not used to Gingrich change attention. They could be a little bit confused. And if you don't really need to optimize, if you if your application is working really fine, you don't really need to use on push at all and push hard recommended to use only when you perform really heavy computations in given components subtree. Then you can directly skip the subtree and it's angular, would not have to check it as as frequent. And why push is not the default change station strategy is another question. Yeah, actually I can share my screen. It might be a better idea. So you can see the questions as well. Is. So here we are on this question, why on push is not the default translation strategy? That's policy for development experience. What's on push? Things are getting a little bit more complicated. As I said, the jurisdiction of Kassem's has a slightly more complicated semantics. So you need to think about the slightly more complicated semantics. And on top of that, changes would not be necessary. Propagate its components which have on push change detection. So this. And in most applications, definitely their own push is like change. It's not a concern. So that's why on pushouts Monday, for one. Yeah. The next question is on Bush truck and truck by how to proper, how proper and best way to use it. Well, it's on Bush where he talked a lot. Tracked by. So. OK. I can explain. We'll track by does exactly. I'm also going to link to some resources for further reading in general. Imagine we are iterating over a collection of users and. We are using energy for for the purpose. So energy for needs a way to find out which. Users in the collection has changed between different runs of the anger agitation. So we run the change station once and we are under the list of users. Now, the second iteration of the change station will run its again. And at this point, we need to find which user have which user has changed. So usually what's changed? What tried by users by default is just to compare the individual users with to check. And this works really well. But imagine. You create a new user object. And you haven't changed the subject at all. I mean, you haven't changed the entity at all in this case and you shouldn't really render. This this item, because you haven't changed its identity at all. You have just changed the object which represents this entity, in this case, the equity check is not the best way to compare items because equal equal is going to return false. And, well, we didn't change the entity, so we don't really want to re render it. In this case, you can use the Trag by function and you can track the users by their I.D.. So this way, if you have user one user with idea one that you can render it once on the second iteration of the of the change into action, you're not going to be rendered S.A.G. instead. You're just going to find out that it has the same I.D. as in the previous situation and you're going to leave it unchanged. So Trag by is extremely convenient when you're using such immutable data structures. Where multiple objects can points to the same business and the same user in our example. I'm going to still link to a resurgence for further reference because it might not be really obvious. It's really interesting problem, though. If you look very abstractly across different frameworks, you're going to see that pretty much all frameworks have the same solution in all frameworks when we're retreating over a collection. We wants to have keys for the individual items in this collection. By default, Angular fallbacks to using the identity of the object, the reference of the object as a key. But you can also specify an alternative key such as the idea. It's really interesting problem. So what are the best reactive patterns of help working quits on push change detection? That's a very generic question. I'm not sure whether I can give a very specific answer. Very reactive, very popular reactive Bartons right now for managing for architectural partners, for user interface are indirects. And generally it's probably the most popular one. And it works well. We don't push. So you can choose to feel free to give it a try. The next question is what tools to use and how to use them to profile Jamelske crypts in angular Web apps. Chrome dev tools is really the best thing that you can use Firefox dev tools. They work really well as well. I'm not as experienced in them. The good news is that in the team we're working on a guy right now on how to profile and your applications. Exactly how much memory your application consumes. We're primarily going to focus on rendering performance. So we're going to cover this CPO time. For network, for performance in general, you shall rendering. So I'd recommend it to use Lifehouse as well. It is already built in into chromed Eiffel's. And if you want to perform a more environments independence. Benchmark, you can use Web page test, web page test. It's a really nice service that allows you to run benchmarks across difference real devices. And it's not going to depends on your particular Internet connection, because what page this is going to run the benchmark somewhere, InterCloud. We have one more question on how to manage module's to keep apps smallest as possible. So this is mostly related to so module's. How do you. There are different people who think about module's differently. Some folks wants to have one module for angular components. That's a little bit too granular, in my opinion, for most applications. Usually the way we think about modules is as lazy loading contexts. So if you want to lazy load something, then you should put him into a separate module. That's very applicable in particular for lazy load its roots. So that's what I would recommend. You just want to lazy load something, just put it into a separate module and use lock children. So more modules or more services, which better affects performance. I'm I'm not sure I exactly understand this question. You don't. Yeah. If you have many services. The more source code you have, the slower your application is going to be, the more source code you lot actually originally as your application loads. The more the slower your application is going to be. So just reduce the number of modules and services that you load during your initials, application, alltime. Yagi interceptors. The next question is interceptors, use or not? And when? Yes, use interceptors, especially if you have two. Process, post or pre process requests a response. That's something very convenient. This is a very, very common concept in many different environments. If you look at the account frameworks there, you have different media. Where's that process, your request? When the server receives it and later on, you can process the response in a similar way. So interceptors are really convenient concept exactly. In such pipelines. This is an interesting design pattern. So if you have looked as a gang of four design pattern, book design patterns, elements of reusable code, the interceptor Potter is actually the chain of responsibility. Potter. So it is a really popular method for processing. Certain identities, certain like request or response in such structured pipeline. And asks which operator when initiative requests. Yes, your very much depends on what you would want to do. We decided to use our energies for our age to be modu because it's very easy to throttle response requests and to also retry them. So I guess these are the most common use cases. I am particularly. So in my applications, I am cautious, I, I don't necessarily go for in with our adjust for age to be. All the time I tried to evaluate the scenario. I'm doing very simple application where I don't have such advanced use cases. I'm directly using fetch with promises. So that's an alternative as well. If, however, you have more advanced use cases, you like to use the expressive. API of just then, yeah, go ahead. Yeah, these are the most common use cases, throttling and retrying requests. Can we use function in view, for example, NGV can show. Yeah, you can. You can do this. And this way, you're going to use it. You're going to invoke not a function, but a method. So method is just a function that is attached to an object and it's invoked in the object's context. If you have something like this. Can't show. And here we have a template. This is absolutely valid. You can also do something like this, I guess. This also works, and here he can have a function. Which does something. This is total vallet. Probably I'll go for the first alternative. It seems like less like fewer indirection since slightly easier to reason about. But both are completely valid. And there are wouldn't be any significant performance implications. Maybe this the first one is also going to be easier to read because you see that you're invoking a method you haven't masked behind. I get there. How to making your test faster? So usually in general, in dual systems, in order to make sometimes in general, like I guess not only in systems, in general, in order to make something faster, is just to do fewer things like fewer instances of it. Baeza is really a great example. Basil is going to run your tests only if it detects that its inputs have changed. So a system like Basle, that is the built system that you are using instead of Google internally. We're going to run tests only if we detect that the source files that are associated with this test have changed. So Basil is definitely one way to make your test faster. It can run the minimal amount of tests if you haven't changed and build files. Baisley is not going to run any tests. An alternative is to use something like Gests, where you can run tests. Which does something quite similar, in fact, maybe it is not as robust as baseball, because baseball is a. It could it could be, actually. I haven't looked at Jesse just recently, but both just and can provide a really great tools in order to incrementally run your tests on the on change. How scalable apps. So how to build scalable apps? We are just following your style guides. Follow well-defined architectural pattern that you have learned from my community, Walpole's or community articles that it's Cale's. Well, such as? And your ex, for instance. And well, you can not also hit the right's architectural pattern from the first time. You usually do many durations. Entry factor rink's. It's very, very rarely a magical bullet. You just have some very high level vision for what your application is going to look like in the future, for how it is going to evolve and to try to beaute your architecture around this as your mentions. Really? A lot of greats practices from solace from the. It's. Acronym with single responsibility, open clause, interface, segregation, dependency, inversion. And I'm missing one Lisco substitution. So if you're folding, you can follow these good practices and you can direct your attention. Apply them in the context of your application. And in general, the scaleable approach for application architecture is usually very iterative. You're iterating over your application architecture until you reach something that you're satisfied that. And how to reuse Bill's files? I'm not sure what exactly you mean by Bill's files here. I would say actually put this question here in the. In this category, so to speed up your builds, you would want to. So first of all, we're going to do some improvements in the build speed, which I view we're able to build your applications faster and faster. We still haven't completed all the optimizations that we can do. So I expect some improvements on due time. Second, if you wants to improve your beaute time and your Butenko really a large application with hundreds of engine modules, I would recommend you to look at Basle again. We have been using Basle on the anger among REPL. We're using it's also at Google on Tenzer for. And many other projects inside of Google, such as Jim El, Google Search and many others. It really helps to view your application at scale. It requires some additional overhead because you need to learn a new build system. But you can also apply your knowledge later on for any technology out there. You can do it. Your anger applications with Basil. You can also. Butte's a C++ complex embedded system, let's say, with Basil. You can use. Basically, you can do pretty much most popular technologies out there, even there are rules for Denna recently, so. I would recommend it to look at Basle, I guess, with this we completed all the questions here in the last. I'll stop sharing my screen and look at the chat. Maybe there are some more. Yes, there are a few more questions. So what does the future of finger relevance in general and your elements there are available? You can use them today. There are some inconvenience to surround the beaute time, and we haven't decided what is the best way to proceed in order to. Bondo in order to allow you to bundle and distribute your anger elements in the most efficient way. So far, the best way to use it to each of your singular elements is to take advantage of the Fenjves build plus month for its stair from community. He has a lot of great resources on how you can achieve this. And your elements are not our top top priority right now, we have a lot of other things on the list, such as making reactive forms. Well, statically typed. So this is something that we're going to focus on first. Well, we are definitely thinking about elements as well. And if you have suggestions, it would be great if you can share them in the form of an issue or even design documents. We will be working on an official RISC process for a community. So this food's. Allow you to provide you like in a more structured way. So you're saying you are capable of tree shaking, can use components from an important module which declares an. Yeah, this could be a little bit tricky question. So in version 10, we're working on a strict moult which assumes that your components are not performing Kennie global side effects. And three, shaking would be simpler. In general. There is nothing in particular in anger that is not true, Sheikh Ible. It is the the tooling that makes some assumptions sense. We have, in fact, a built optimizer that looks at your applications, just file your applications, not do files, but source files and tries to make assumptions whether a particular clause that you have or like, for example, a component declaration is pure. Which means it doesn't perform any global side effects. And we marking such declarations as pure so that we can enable later on the optimization pipeline such as Tercer and Westpac, to remove and to to drop this component. So these are things that we do right now. But with version 10, we'll be able to do them more aggressively. So to answer your questions, yeah, in general, Angourie three checkable and we do it with three shaking in lines. There is also one more question by Santoshi on is too complicated to setup in his town? Is there any guidelines or jokes you can suggest? Yeah, basically it's an independent effort from the anger team. There is an entire baseball team that is working and maintaining this built system externally for outside of Google. And they have Basle dot io. So I would recommend it to look at Baisley Ohio. It's you might not be completely obvious because baseball is just a tiny core. And to use baseball for different technologies, you need to use. You need to understand how to take advantage of something like like plug ins for Fasal. For example, there are rules or plug ins for using Baeza with angular ones, for using Baeza with typescript in particular, and so on and so forth. So after you understand how business works on high level and you understands the syntax of its configuration and language, you can look at these specific rule providers to figure out what is the way to configure them. It is quite similar to wetback in the sense you have wetback, which provides a core and you also have different wetback plugins. So you're using these plug ins from community members in the to assemble them together. And Butte's your pipeline. Yeah, it's very similar to your center battle. It's more similar to what, by Kelsey? Yeah. OK. I think I answered all questions. If you have any other questions at. You want to ask? Feel free to reach out to me on social media as well. Thanks a lot, Minko. It's it was a great, great session. Thank you so much for this deep answering. So if you have any questions. Now is the chance. A last minute chance. OK, we have one. How to create validator for control. Interactive forums. Depends on another control state. This is a little bit more specific question, I guess. It will be better if you if you can ask me, like, either. Separately or you can ask him to take over for and I can make sure it's we look at it. We can do. I would. I don't think I'll do well in life. Calling right now just shared the Article four on Pushkin's detection. In the chat, so you can look for resources for further reference. Yeah, yeah. So one more time. Thank you. Thank you so much. ALL Thank you, Mincome. It was great time, second time on the Angela online meetup. So, yeah. Big applause from Incoll. This is the now. This is now the time for the big applause for this great guy. And I hope we see soon. So thank you so much all for today. You think working?