Angular 14 is definitely one of the most significant and powerful releases in the last couple of years. In this video, I would like to cover one feature that slightly dissolved in the hype around standalone components and typed forms. This feature is "providers" property in routes. How does it work and what impact on current Angular Dependency Injection it has - all these questions will be covered in this video. Let me know what do you think about it? Let's discuss it in the comments!
Angular courses made by Dmytro - https://bit.ly/df-courses 💥 ✂️
Use coupon YOUTUBE_DISCOUNT to get a 10%-off discount ✂️
Source code on GitHub: https://github.com/DMezhenskyi/new-router-features-angular14
Time Codes: 00:00:00 - Intro; 00:00:40 - Describe a demo project; 00:02:18 - Describe a use case to implement; 00:03:47 - Project code overview; 00:06:13 - Route providers in action; 00:11:51 - Impact on current Angular DI; 00:13:43 - Outro;
Short Frontend Snacks every week here:
Twitter - https://twitter.com/DecodedFrontend Instagram - https://www.instagram.com/decodedfrontend LinkedIn - https://www.linkedin.com/in/dmezhenskyi
#angular #angular14 #webdevelopment #ng
Hi everyone. Welcome. My name is Mattoamshanski. I'm the author of this YouTube channel about advanced angular tutorials called Decoded Front End. And I continue to share with you new angular 14 features. And today we're going to talk about a new property for angular road called Providers. We will see it in action and we will check what kind of impact it has on the current angular dependency injection. So, subscribe to my channel and let's get started. This is a very simple angular application I created specifically for this tutorial. And here I will be showing new angular router features which are available since angular 14. So let me quickly on board you and demonstrate this application. And I will also give you some context about what we are going to achieve in this video and what we are going to implement. So, as you can see, this application consists from three pages. The home page you see right now. And then I have Users page. This page has a child component that represents this user list. It is a smart component. This component injects the service that pulls data from the server. And then with Ng for loop, we render the list of fetched users. You can also click more details button and then we will be redirected to the separate page. And here we will pull data for this specific user and show more details about the user. So I can also go back and also I can go to the Admin page and Admin page you can see also very simple one. And here I reuse this user list component. And this is absolutely the same component what I'm using right here. So I decided to reuse it in my Admin page as well. Now let's talk about the task we are going to implement. So imagine that we got a requirement that we got a new API from Backend Team or whatever, and we want to test it out or try it out in our application. But we don't want to roll out it completely for the whole application. We want to try it in some smaller scope. And if everything is fine, then we could already roll out it for all users. And we decided that we want to use this new API. So we have to create another service. And User List component should use this new service only within the Admin role. The rest of the application should use Legacy API and legacy Angular service that knows how to work this Legacy API. So I hope you got the idea of what we're going to achieve. And let's switch to Vs code. And here's the source code for this application. However, I will not be showing you component by component, although how it was implemented, because I will leave the link to the GitHub to the source code. You can clone it. You can clone exactly this state. So you can on your own investigate how it was built. It is very easy. And because this video is not for beginners, I will focus only on the things that are really matters. And let's have a look at the user list component itself to see how it is implemented so you get a better understanding of what we are doing. And this is how the component looks like. You can see very straightforward, we inject the User loader service. This is the service that basically does calls to our legacy API and it returns some data. For instance, we load users right here and we then assign everything to the user's property. And after that in the template we subscribe to user's property and using Ng for loop, we render all of them. So this is how it looks like. Besides that, I prepared also alternative experimental user loader service. This service is supposed to kind of treat it as a service that knows how to work with this new experimental API I mentioned in the very beginning. So we would like to instruct Angular to use this service for all components that belong to admin role, including our user list, because this user list is being used for users page and for admin page as well. And this service should be replaced for admin route. How we could achieve this, we could achieve it quite easy since angular 14 because now Angular road has such a property like providers like that. And already here I can register Angular services that supposed to be single tones in scope of this road. So I can do here the following thing I say that provide user loader service, but I'm going to instruct Angular. That when Angular will try to resolve this service for admin component or some children. For admin component, please do not use the User loader service class, but rather use existing experimental user loader service like that. If this everything looks like a magic for you, I have dedicated video about dependency providers in Angular link will be somewhere there, so you can check it out later. But now we can save it and enjoy the result. And you can see that for the admin page, the user list component resolved our experimental user loader service instead using user loader service. And if we navigate to the users page, this user list component, this specific instance of the userless component that belongs to user road, it uses the legacy service, right? So such a way we could replace the service implementation on the road level, which is really cool. Of course, it doesn't mean that it works only with standalone components. You can see right here, I lazily load directly the component without model. And if you didn't hear about standalone components yet, I recommend another video where I covered this topic. It is a new thing that comes with Angular 14 in developer preview, so you can check it out later. But yeah, it works with any role. You can basically grab those providers from here and apply them for users Page, which kind of uses the models. And if I save it, we should get the opposite result. So admin Page uses the legacy service and when I switch to users, you can see that I switched to the new implementation and it works without any problem with experimental service. But you could also say like robot, we could solve it by applying providers on the component level directly to the admin component. Indeed, we could apply this provider directly in our admin component. And if we save all those stuff, we will get actually the same results. You can see users pay lots from legacy API and here we can see the new API in action. However, despite the behavior is the same, those two approaches have one small difference. Namely we configure two different injectors. Currently, what we have done, we configure the node injector for admin component, but here we configure completely different injectors that is created specifically for this road. And this injector belongs to another injector Hierarchy. If you didn't know in Anglor there are two injector Hierarchies, node injector Hierarchy and modern injector Hierarchy. The last one, by the way, was renamed in Angular 14 because standalone components make Ng models optional. So that's why model injector hierarchy and model injector was renamed to environment injector. And I can easily prove that those are two different injectors by. For instance, I can remove this part from here and leave only user loader service. And now the result will be that admin user will be using the legacy server service. Sorry, because node injector hierarchy has kind of priority over the environment injector. So that's why Angular resolved first this user loader service. If I remove that, then Angular will switch to the environment injector hierarchy and resolve this provider. So you can see that the new service is being used. And now let's quickly recap what do we know about the algorithm that resolves dependencies in Angular? Dependency injection. And this is the schema that shows how dependency injection is being resolved in Angular right now. So we have some grandchild component that declares the dependency on user service. When Angular tries to resolve a proper provider for grandchild component, first it starts to resolve it in its own injector. If it doesn't find it there, it tries to resolve it in the parent injector and then it goes up through the node injector hierarchy until it reaches some component that has provided for the user service. In our case it is a root component. So Angular will resolve this instance of the service to our grandchild component. If there is no any provider inside the node injector hierarchy, angular would go through the node injector hierarchy. First it doesn't encounter any provider. Then it returns back to the component where this user service is declared. And then Anglers tries to figure out if this component belongs to some router that has providers. In this case it switches to the environment injector hierarchy and starts to resolve these dependencies from the router injector first and then if there is no provider there, it will go to the root injector and then to the platform injector and so on until it rises. The error if it doesn't find any provider. By the way, if you lazily load some model inside your admin route for instance, then rotor injector become the parent for this lazy loaded model. It is also worse to remember. All right guys, that was it. I hope this video was really useful and if so and if you like it, please share this video with your colleagues and friends in your social networks. Also, you can subscribe to my Twitter, Instagram and LinkedIn accounts. There I publish every week some short tips and tricks regarding front end and I call them front end snacks. I'm pretty sure you will like it. Besides that, please leave your comments in the comments section. I would like to know what do you think about this new feature? Maybe you know some interesting use cases where you could only apply it or you can drop literally any comment because every activity under my videos helps this channel to grow and if you would like to support me and everything what I'm doing and additionally get some cool knowledge, then check out my video courses. The links will be in the video description as well as coupon codes. And this is everything I wanted to say. I wish you productive week ahead. Stay safe and see you in the next video.