Advanced #Angular Patterns - ForRoot & ForChild (2021, Decoded)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi there my name is mitch mzenski and today we're gonna talk about design pattern in angular called for root and for child if you have ever used the router angular router you probably have already seen this pattern but why do we need it and which problem does it solve this is what we'll learn in this video today but before we start to code anything there are two preconditions and the first one is that you have to understand at least on the basic level how works dependency injection in angular and the second precondition is that you have to have some experience already with angular and when the first precondition you can solve by watching this video about dependency injection in angular about the second one i can recommend you the course which i personally used many years ago but it's still relevant you can also use it so the link will be in the description and if you are too new in angular this is perfect starting point but let's get back to our for root for child pattern all right guys i did some small preparations in order to save your time and i generated angular workspace by using ngcli and also inside this workspace i created one application this one demo application and the polling library and they are absolutely empty so we can have a look at the polling library and you can see that uh there is pretty much nothing this is empty service which does nothing this is the empty model and as well as components so nothing interesting here so far we can close this polling uh library and let's have a look at the demo application and inside the demo application we have of course there is the app model up component uh but then we have uproading also and you can see that we have uh two roads one is just for home component and another one is route called lazy and it loads lazily the model which called lazy model this one and uh you can see the those two modules here the first one component this is the now the simplest model in the world so this is just empty uh model with empty component and lazy model it's like also very simple but it has a laser routing which has this uh road there so this is pretty much everything uh you have to know uh no inside the app component here we have some small template yeah we have this router outlet and we have the button which navigate us to laser lazy road and let's have a look how it looks um in the real application so this is our application right we have this button lazy load if i click we navigate it to the lazy lazy road and we see that lazy lazy model has been loaded good so now let's go back i will close this everything so far and let's jump to our polling library so we all know i hope what is polling so this is when we with some interval we request the backend for some changes and if we have some changes we can render this on the client side and whatever of course we are not going to implement the whole polling mechanism yeah we will implement some faked one but just in order to demonstrate you uh the use case for our pattern for root and let's go to the polling service and create one so i will create the public method this method is going to be the observable and i will create this with the timer method so like this and it will be general emit value every second as example and then we will do the next thing we will apply operator called share reply why it doesn't find it okay let's import this manually so this comes from operators and here it's the timer we have the share replay operator and if you don't know what does share operator it shares the latest value from the stream to the new subscriber so every time it will be emit zero one two three four and when after i don't know third uh value emission the new subscriber comes usually it would get again zero one two three but we share reply it will uh get the latest value so three and then it will uh proceed to receive the four five six seven and so on so on so i hope it's somehow clear otherwise you can read documentation about this operator so we have this polling right and uh here is a little bit of history of angular until version 6 of angular we didn't have this fancy feature like provided in which is really cool it makes our services too shakeable and using this provided in root we can be sure that it will be always singleton in scope of whole application right but until version 6 as i said we didn't have this option and the only one way was is to provide this inside the model inside the providers or component providers but yeah whatever so we did it like this we used the providers and here we provided our polling service like this right so in this case we as a author of library yeah we make our library easy to set up for the library consumer so they can just import the model of our library in some another model where they're going to use our library right and this is pretty much everything because uh providers will be registered with this model yeah they don't have to do it manually of course you can enforce them to register services on the application side but if you have dozens of services that's quite bad user experience right and um we do it using the we were doing this before by using these providers so and now let's connect our library to our application so first of all i have to build my library let's run ng build polling library and i will build this in watch mode because i want to immediately see the changes in my application okay now my library is yeah it's working fine so i switch back to this console and now let's import our polling uh library into our modules in inside the demo app so we go to the home right and inside the home model i will import my polling model okay it shows the wrong path so i want to call the polling like this all right and the same thing we will do also for our lazy model so like this and i will import this somewhere here and inside the imports we are going to import our polling model so like this and we have to use this polling mechanism somehow right so i will go inside the component and somewhere here i will inject this everything like i'm injecting polling service yeah again why vs code doesn't recognize that this is correct import all right so uh yeah we injected the polling service and right here i want to write something like polling count times and then i will subscribe to our polling uh uh polling polling here and i will use the async pipe in order to subscribe to this everything right and the same we will do inside also the home component so polling polling service again this polling and the same i will take from this part um and maybe and maybe let's uh pulling cold times we said lazy in order to yeah see that which component is being active right now and here we will just place it uh like this so i think we forgot nothing right so let's have a look how it looks now or you can see that polling um works so it's counts things but then we load lazy we get probably somewhere no ah we already on inside the lazy all right let's reload so we see that uh counter works let me open network then we uh click on on the lazy lord lazy and we see the problem that it started to count from the uh zero so but why because we you may remember that we um fix this by using this share replay so this is not something with our stream the problem is that this is another instance of our polling service and if you watched my video or you just know yeah this how works the dependency injection in angular you should know that if you load model lazily like this like this one it creates the child injector for this model and because we provide our polling service within this model which is provided into the lazily loaded model that's why we have two different instances first instance for lazy loaded injector and the second one is created at the application root because we defined this in the home model which is eagerly loaded that's why we have two instances and this is uh kind of the problem right because we expect that um our service is single tone in scope of the whole application so how we as the author of the library could solve it uh so we have to split somehow this part from the declarations providers and declarations and uh how we could do it so this is where this for root pattern comes into the play and we can say that this uh model which model it's a class yes so nothing stops us to create some properties here right or methods so we can create a static method which by convention called for root right like this again you can name it as you want this is just a convention and this method this static method returns such a thing called model with providers and this is generic type so we have to define which exactly model it returns and in our case this is polling model so we do it like this and of course we have to return something so we return the object and this object has two uh properties we have to provide ng model which is our polling model this one and then we have to provide providers which is optional but in our case we have to provide it and we move our this provider so we grab it oh damn it we grab it remove from this provider and we provide it here and then the most interesting thing we import this for root inside our app model so we go to app model and here we do our polling model polling model and then i call for root and what happened when we do like this when we call for root we are not importing this model the whole model we just import this part we provide only service in this case yeah so these guys these declarations things like that they are not imported with uh with this method all right so we provide here only only services and because they are provided inside the app model we can be sure that they are single tones in scope of whole application and already inside our home model because we import this like without for root without calling for root in this case only declarations will be imported inside the home model and the same will be also for lazy model right here and if we save it like this and then we reload our application you can see that it counts but when i click load lazy we see that it proceeds to count from 8 so it's the same instance of the same service and it renders it here so if we go back we see that doesn't start from the zero so this is how you could solve this many years ago until angular 6. however nowadays we have this nice approach with provided in so where is this so we can use provide in root and in this case we don't need to to care about this so we don't need the uh for root anymore it would work just fine but let's revert think reward this and revert also our injectable however this pattern also allows you to do another cool thing and it allows you to configure your lazy loaded models some are differently or pass some config to it and this is exactly what angular router does and we will have a look at the source code later on how it was implemented how they're using this pattern but let's implement maybe such a thing like if it's a lazy model it should pulling our server not so often not every second but maybe i don't know every three second right because if it's lazy loaded model most probably for users it's not so important to get the most uh latest data from the server so we can decrease the uh load on the server right so it could be a kind of configurable model so we can create the same static method and call it for child now again this is just convention for child and this for child would have some config config and let's create some interface i will create it uh inside the service i don't want to create separate files for this all right but in real application i would recommend you to split things all right and it has some inter interval property which is just a number and yeah and we just have to import this this interface right there okay and then we also return the model and g oops ah yeah we have to define the return type as well so i will copy it from here because it's the same type right so that we have and here then inside we need to engine model um polling model and then providers and we have to provide them and we have to provide also polling service yeah because we want to have the separate instance uh for lazy loaded model right and then besides this we want to inject maybe some this interval which uh user will provide with this for child and enzyme configured pass some interval and then we want to inject our config which uh developers which are using our library can provide to it and um yeah let's create the injection token for it i will create this also here inside my service so export and this is going to be new injection token which will have the number type right and it's going to be interval string like this then we have to provide this injection token inside our polling model so i will create the provider object and we say that we provide interval here we go and we say that use value from the config so config interval like this and maybe if it's empty let's give some default one two second if this is not clear for you what i have done another video recommendation i have the great video about this dependency provider so check this out but pro if we provided already this thing we can do such a interesting thing and inject our uh this injection token to our polling service right interval and it's gonna be private and it's going to be the number all right and and and and i i will do it optional as well optional so here we go and now we can use our injected interval and instead of a hard coded one this one we can use it like this so i can save it and now if we reload this everything we see that it doesn't count why ah yeah makes sense because when we inject this for root we don't provide uh this interval dependency injection token right so it will be empty at this at this time so we have to add also the similar check so if it's undefined by default it should be one second right so oh yeah i forgot another thing yeah so we have to now provide our polling model we're using this for child so we will go to to our lazy model and here we will say that for child and it requires the config right so we provide it like this i say that interval let it be three seconds now so we configured for lazy component uh we use this for child thing this config and for the whole model or where this app model for app model we use for root so for root provides nothing we see right we provide only polling service and by default it will be one second because it has nothing to inject yeah we we don't have any provider for this uh internal injection talking here right so it will be there one second but for lazy load we do we register our model differently we also provide this interval so this interval will be injected into our service constructor right here and here will be the value which which we defined inside the config inside where is this lazy model this one this what will be injected right and now if we um let's go back to our root so it counts every second and now i click load lazy and you see it's every three seconds so it's really really lazy model all right so this is how you can configure this is the for root for child pattern in action you can see of course you could handle this with only one method you could create something like i know static with config and provide this everything i know provide the config there then okay let's implement it so we can copy this thing here config we have to copy there so like this right and by default it would be let's say one second and now you have to and you could do this also optional so in this case you would need to handle this condition and yeah and then you would need to use everywhere this with config so for root as example you would pass it like this always config come on ah this is vs code somehow stupid yeah so uh let's then config this for lazy model and then we don't need this for root for child so i can save and use this just with config yeah only one method then and the same effect will be here so that's every three second is being counted then i damn it i have to reload this so you see every second then i load lazy and it starts from the zero first and then it like counts very very slow so uh this is yeah example i uh i can show you also how the internals of for root for child pattern looks in angular router so let's open our angular so this is a source code of angular and this is our for root and for child methods yeah so and this is road router model and if you open the for root you will see that they providing i know rotor providers what what do you want it provides the rotor providers then yeah you see a lot of different services whatever root guard yeah it means that if you're trying to import twice this rotor model it will throw the error for you and yeah so you can see how many things are being injected and the thing is that it should be injected only once in this case it will be singleton yeah in scope of whole application but for child it just returns the router model and just the it provides only roads uh takes it here and use this helper in order to create create our child roles yeah so this is how the angular implemented this pattern also you can see the similar use case uh inside the ngrx library if you are using this you can see they have um for for feature um static method and this for feature methods it merges there some you have feature yeah and you have to have for this feature some slice in the global store so this for feature merges this slice into the uh global store and you can safely use it with lazy loaded modules as well so this is yeah how they implemented this and i'm pretty sure you saw a lot of similar use cases for this our polling mechanism it's just one of use cases i don't know how useful or not it is but yeah i hope you have now better understanding why do we need this and which problem does it solve all right guys that's it for today just a small remark that use this pattern wisely and in ninety percent of cases this is enough to use provided in property and use this for root for child pattern only if you really really need it and of course share this video if you find it useful also leave your comments and i wish you productive week ahead and see you in the future you
Info
Channel: Decoded Frontend
Views: 47,235
Rating: undefined out of 5
Keywords: angular forroot, angular forroot vs forchild, angular forroot method, angular forroot not working, angular patterns, angular architecture patterns, angular advanced tutorial, angular advanced concepts, angular advanced tips, angular 11, angular tutorial, angular 2021 tutorial, angular 11 tutorial
Id: PU_xpHxZkrE
Channel Id: undefined
Length: 32min 3sec (1923 seconds)
Published: Tue Mar 02 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.