Video details

New Way to Inject Services in Angular 14?

Angular
06.01.2022
English

💥
Angular courses made by Dmytro - https://bit.ly/df-courses 💥 ✂️
Use coupon YOUTUBE_DISCOUNT to get a 10%-off discount ✂️
Angular 14 is about to be released and it brings a lot of new cool features. One of that features is injected() function that has been existing since Angular 9 but with Angular 14 it gets more areas where it could be applied. About that, we are going to talk in this video and have a look at some base use cases. What do you think about it? Let's discuss it in the comments!
🕒
Time Codes: 00:00:00 - Intro; 00:00:50 - How we could use inject() before Angular 14; 00:05:39 - Scenario 1 - Injectiong Injection Tokens; 00:08:37 - Scenario 2 - Simplifying Inheritance; 00:13:58 - Scenario 3 - Inject Function/Composition Function; 00:18:26 - Final Notes; 00:20:29 - Outro;
Source code on GitHub: https://github.com/DMezhenskyi/angular-inject-function/tree/final-state
↙️
Short Frontend Snacks every week here:
Twitter - https://twitter.com/DecodedFrontend Instagram - https://www.instagram.com/decodedfrontend LinkedIn - https://www.linkedin.com/in/dmezhenskyi
🔗 Useful links about this topic Chau Tran (@Nartc1410) https://nartc.me/blog/inheritance-angular-inject Younes Jaaidi (@yjaaidi) https://marmicode.io/blog/angular-inject-and-injection-functions
#angular #webdevelopment #ng

Transcript

Hi everyone. Welcome. My name is Mitromzhenski. I'm the author of this awesome YouTube channel, the channel about advanced angular topics. So do subscribe to it because you can find a lot of interesting angular videos right here. Angular 14 is about to be released and this release brings a lot of interesting features like standalone components, typed forms, and also it improves a little bit the old new function called inject. And in this video we will see what new comes for this function in angular 14. So stay here and let's get started. So, as I said in the intro. This function has been existing in angular for a while, namely since angular nine, I believe. In which version did we get opt in, Ivy? I believe it was angular nine. So since that version we can use inject function, but the use cases were. A little bit limited. So let's quickly recap where we could use this function since we were nine until now. We could use it inside, for instance, if we have injection token. And if you didn't know, now you know that you could provide such a. Config object for your injection tokens and. You could provide it immediately in root, injector using provided in root. Likewise we do for our injectable services. And if you use provided in root. You have to use factory function. And in the factory function you kind of resolve the value for your token. But sometimes in order to resolve the proper value for some token or some. Service, we would need to inject another. Token or service, and inject function allowed you to do that. So imagine that we would like to return the default browser window if we run our application in browser. Otherwise we would like to provide some mocked version of the window. So in this case we would need to inject the platform ID first. So I would create constant platform and then I would use the inject function. And make sure that you import it from angular core, not from angular core testing. So I could import this function and. Then I have to provide the actual token I want to resolve. In my case it's a platform ID. But here could be any service you. Would like to inject in this directory function. And then I would do very simple check, something like if platform equal browser. Then I would return the window. Otherwise I would return some mocked version. In my case, it is going to. Be the empty object and I cast. It as a window and then I could save it. And then somewhere in my component I. Could inject this injection token and then. Console log the value. And if we go to the browser and reload the page, we will see the window object that we just console logged. By the way, this is just application, just an example I created for this video. But you can see that our window has been resolved properly. So this is the typical use case. For this inject function. Of course you could use it in the factory functions for services. For instance, I have some dummy store service really like just mocked version of the Erect store or any other store. You could potentially use in your application. But inside injectable we also have dependency. Providers and namely we could use factory dependency provider and inject the same way some service or injection token inside this factory. So before angular 14 we could use our inject function only within this injectable. Annotation or we could use it in. The factory function for our injection token. By the way, if you are not aware what are dependency providers in angular. Like use Factory, use Value, use class. And others, I have a dedicated video about that. The link will pop up somewhere there or there. So after this video you can check out that one. But let's get back to our inject function and I will remove this part because I don't need it actually. And let's talk what will change with angler 14 that is being used for this project. By the way, I'm using release candidate version but at the point when you are watching this video, probably the stable version of angular 14 will be released. So you will be using just angular 14, whatever. With angular 14 you will be able to use the inject function not only. The cases I just described, but you. Will be able to use inject function inside your components, directives and pipes how it would look like. So in order to inject some service. Or token in the angular component, you would need to do something like that. So you have a property, let's say window and then you can say inject and then you define what are you going to inject. So in my case I'm going to inject the window and type script complaints because it is because I have two identical properties window here and window there. So I can remove this one and such a way I achieve the same result as it was before. If I save it and go to. The browser and I can reload it. Of course, and you can see that it still works. So, what kind of benefits do we. Have using this in check in this particular case? First of all, if we revert the. Old notation we can see that the. New notation is way more shorter rather this one. Would you agree with me? It is not a big deal actually. But still the second and more important thing I would like to highlight is. That if we use inject annotation in order to inject some particular token, we. Have to explicitly describe the type of. The object or class that will be injected. And actually it is very error prone because if we type string TypeScript cannot give us a hint that we made. A mistake and we can think that we are injecting the string but in fact we are injecting the window that has completely different type and it could. Be cause of the runtime error when. We use the inject function, inject function. Can infer the type from the injection token. So if I check what the type. For the window, currently you can see that this is the type window because it infers the type from the injection token which is really cool. So this is the first scenario where this inject function inside the component might be useful. The second scenario is about inheritance in. Angular that should be of course avoided as much as possible we should prefer composition over inheritance but sometimes we use inheritance, sometimes it is useful. Imagine this very easy example. So I have some widget based class that has some common inputs and providers that are required for every driver widget. And I have a couple of them, I have readonly widget and I have interactive widget and this is how they look like. So the read only widget, it just. Displays some information and with interactive widget user can obviously somehow interact. It has some buttons so user can reload data, add new item, whatever, but I hope you got the idea. So we have two different types of widgets and currently every widget extends their widget base in order to inherit common inputs and some common providers. You can see that the same is done also for read only widget. So yeah, we just inherit stuff from the base class but our interactive widget. Let'S say smarter a little bit, it. Should know how to perform different actions like refresh data or add new item. So we would like to inject a. Service that contains the logic for all those actions. So we would use our constructor in order to inject a service called actions and it is action service I believe. Widget action service, I name it like that. Now TypeScript tells us that we have to call superclass. So let's call it so super, here we go. But still it is not enough. So TypeScript says okay, we expect two arguments data provider and settings provider that. Has to be also injected. So it means that besides this widget action service we also have to inject those two services, right? So I have to do something like. That and then import all missing services like that. Then I have to remove this protected and provide data service and settings like that. Well, a little bit too much blueprint in my opinion. And also keep in mind that if we change in the base class for instance the order of injected providers or if we would inject additionally another service. Or token in this case we would need to adjust all our derived classes as well. That is also kind of additional work that we would like to avoid. And let's have a look how inject. Function could help us to reduce amount of the boil print right here and let's get started with refactoring of our widget based class. So we could extract our injected services. From the constructor and we could inject. Them using inject function right here. So I would do something like that and I have to import my inject function and the same I'm going to. Do for my Widget settings service. Here we go. So if I save it right now. I can actually remove this part from here, I just leave the super call. And I can remove data provider and setting services from here and leave only. My Widget actions service and then I could use it somewhere in my refresh. Method and so on and so forth. So such a way when we change. Or add new injection to the base class, we don't need to adjust our. Derived classes which is actually very convenient. Very cool and as you can see, we drastically reduced the amount of boil print right here. And there is a third scenario and currently I cannot tell you if I. Like it or not, I need a bit more time to play around with that but still I think it is worth to show you and it is. So called inject function or also I heard composition functions. I believe there is no official naming for these kind of things but the idea is the following. So imagine that you have the function something like inject state and here you inject some store, for instance in JRX. Store, so you have something like that. And then I would like to select the user's state. So I want to get all my users that are currently added to my global store and then I could create a property called for instance state and then I could inject state like that. Or we could even improve a little. Bit the inject state function by making this key dynamic. So I could take the key as. A parameter for the function and then. I would use it instead my hardcoded. String and then inside my component I. Could already define which exactly store slice I would like to inject. And the idea behind this function is. That a function will inject all necessary. Dependencies for the component. In our case it is a store and it can perform some operations, some configurations like in our case we selecting. Some particular store slice and then it. Injects this everything into some property. It looks nice, I like it to be honest. Indeed it looks cleaner because we could extract all the store related stuff into the separate function. Such a way reducing wheel print. I think I say this word too often in this video, sorry about that. And the second thing is that inject function or inject state in our case is reusable and makes the compositioning for our components way more easier. Those are cool stuff really. The only one concern I personally have is that this inject function hides dependencies and when I inject state, for instance, into my component. I don't know what exactly is being injected. This inject function kind of black box. I don't know. Is it inject only the store or store and some other services? Or what is going on under the hood? I don't know. It is hidden and this is something I don't like. But also, I don't want to charge it ahead of time. I would like to observe it a little bit. Maybe some new patterns will grow from it. Maybe there will be some conventions we don't know. Likewise with standalone components, let's see them in action first before we start claiming. That without Ng models, the structure of our angular applications will be destroyed and things like that. So those are my thoughts regarding this. New functionality, patterns and standalone components. Maybe my thoughts will change in the future. They will definitely change. And of course I will share with you my new vision about all those stuff. But so far it is as it is. And before I say goodbye to you and start promoting my courses, I would like to drop a few notes regarding this inject function. First of all, keep in mind that this is not a new way of injecting services and injection tokens in your components. Use them only when it is necessary in the examples I showed to you, especially first two. Otherwise, please stick to the traditional injecting via constructor. So don't go crazy with this inject function and don't use it everywhere. The second thing is that you are allowed to use inject function only during the constructed time. So it means that you can use. It either when you initialize some class property or you can use it inside. The constructor, but you are not allowed. To use it inside lifecycle hooks or inside some other methods. So it is available only either here or there. This is the second one. The third one. The third one is that inject functions are not analogs of react hooks. Those are two different things. They solve two different problems. All right, so angular doesn't turn into react. Forget about it. And the last but not least is. That if you don't like this new feature, please drop your comment about that. Do not dislike the video because you disliked my previous video about standalone components. Like a hell. But video doesn't deserve it, okay? So if you don't like it, leave the comment. Do dislike when you really didn't like the video itself, not because you didn't like the feature. Okay? So I hope there's no misunderstanding anymore regarding this thing. Otherwise, I really hope that you enjoyed this video. And if so, please share this video with your colleagues and friends. I would highly appreciate it. And also, don't forget to drop your thoughts regarding this new inject function. What do you think about that? Maybe you know already some interesting scenarios or use cases that I didn't cover in this video. So I think it would be a. Very interesting discussion for all of us. Don't forget that I have some video courses about angular. You can check them out following the link in the video description. There you can find also coupons if you want to get the course with some discount. And besides that, I will attach a. Few useful links to blog posts from my Gde colleagues. They wrote exactly about the topic from. This video about the inject function. So if you would like to read more about that, you can follow those. Links and read those articles. They are very cool. Otherwise I would wish you productive week ahead. As always, stay safe and see you. In the next video. Bye.