Angular Design Patterns – Bridge [Advanced, 2020]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we will learn how to use design pattern called bridge in context of angular hello guys my name is Dmytro Mezhenskyi. In previous video we learned what is control value accessor in angular and why do we need it. Today we will have a look at bridge pattern knowing these two things will allow us to implement complex material form field which we will do in next video. Today let's get start with bridge pattern! So here you can see widgets which we're going to implement in this video there is a widget 1 and widget 2 and if i click refresh button it does refreshing and if i do the same with second one it does the same as you can see they have something common and this is the header which has a title and a refresh button but they have completely different content inside inside the first one we see content which shows the weather and the second one is completely different and shows velocity of some i don't know sprint and both have different implementation of refresh mechanism as well because most probably they would need to call different endpoints and you can see that they using different spinners so the refreshing strategy is completely different so okay let's start to implement this widgets in order to save your time i did some small preparation and i created the patterns example model where i will be showing these examples and let me quickly show you what i have done here so i will start with pattern example model and here's the pretty simple stuff i just declare my components and then i do import of all necessary models which i need to to make this component properly work and i also export some components which i'm going to use outside this model then i will show you widget proper this is the component which yeah very simple it's empty inside it has some very simple template there is the header which we saw just few seconds ago there is the section where we are going to render the dynamic content for our widget wrapper and it also has some i don't know css styling so that's nothing interesting here then we have to another widget so it's already concrete implementation of some concrete widgets so the first one is velocity widget you can see this is also a very simple angular component it has some methods which first one is load it simulates the http call to the server and refresh it also simulates the refreshing mechanism and it also has very simple template we have the spinner which is being shown when we do refreshing and also some style was attached during the refreshing so it will decrease the opacity of content and there is content itself and the very similar thing i have done for weather widgets so also you can see similar logic inside there is just different naming and and that's it and the template also you can see quite similar but just different uh loader i'm using here and a little bit uh different content so that's pretty much it the last thing what i'm doing is of course i import my component oh sorry component model into the imports in my app models ts file right here right and that's pretty much it what i have done and now let's maybe render these three components and see how they look independently i will comment the component from previous video about value accessor and i will render here my app widget wrapper first and then we have app let's say weather widget and also we have velocity widget so lost city all right and let's go to the browser and see how they look like so yeah you see they were rendered independently so we have independent wrapper where we have our command template our title and refresh button and we have the concrete widget with the which shows weather and concrete widget which shows the state of our spread okay our next task would be to render this concrete widget inside our widget wrapper so we want to reuse this whole wrapper hold this html right and we want to just replace the dynamic content of our widget and in order to do this i will use the ng content or it's also called content projection and i will go to widget wrapper content and inside the section tag i will use ng content and how works this ng content if we put something between text of this component as example the weather widget so this weather widget will be rendered instead of this ng content so let's have a look i will save it i will save this part and if we reload we see that our concrete weather widget was rendered inside our wrapper and if we do the same but with this velocity i will commend this out we will see that now our sprint widget was rendered inside our widget so the first problem solved and the next thing what we have to do is to trigger somehow the refresh mechanism of this concrete component when we click the refresh button in our widget wrapper and to achieve this we need to do two things the first one we have to create the handler of the cli for the click button and the second thing we have to somehow get the reference to this component and trigger the refresh method there and let's start with the implementing the click handler so i will go to our widget wrapper so here we go widget wrapper and here we have our button and i will do the next so if we click on this button will trigger on refresh method and i have to create this method in my ts file as well so i save it here i go to my ts file and just below this engine i need i will create our own refresh method now i want to get the reference to the component which i'm rendering uh instead of our ng content so in our case it's velocity widget and i can do this using content child so let's go to win the widget wrapper and here in the top i will just import the content child decorator this content child will allow us to get reference to our component which we are rendering uh here so in our case it's velocity widget so i have to tell here that here i get the reference to velocity widget component and we'll assign this to the variable or property which is called widget and also it will be type of this widget component and on refresh because i have only the reference to our widget i can trigger our refresh method and if i save and i will go to our browser and i click refresh and we can see that refreshing mechanism was triggered but what will happen if we instead of our velocity widget we will add the weather widget let's have a look so i will go to our app component and i'll just command this out and uncomment our widget a weather widget sorry and if we go to browser click refresh nothing is happening and if we open our debugger we see that we have an error here and this error says that cannot read property refresh of undefined and it makes sense because if we have a look on our in our wrapper we see that we trying to get reference to some concrete component in our case it's velocity widget but now instead of velocity we have the weather widget so that's why it was undefined and how we could solve it we could actually create another one uh content child but in this case we could rename it to weather widget but in this case we have the reference not to velocity but weather widget right and of course i have to import this here and now we have also reference to our weather widget right and we could do the next ugly thing we could do some if statement and we could check if the widget exists then trigger refresh for this widget then if as example uh whether widget exists trigger refresh method of this weather widget correct and yeah it could work we can go to the browser and check one more time so if i click refresh and indeed it works perfectly as we expected but do you see any problems here if you don't then let me uh a little bit uh complicate the things and let's say that when we do ngon in it for our widget wrapper we want also request some data so we have to do the next so inside the widget inside that you only need we have to call the load method and here we have to call the load data and of course we have to say here that static true i need this because i'm using uh these um references in ng only need and usually if it's static false which is default value we can access this only in ng content in it hook but if i want to access this reference before uh change detection run i have to use static true and it will be available in on ngon init lifecycle hook and yeah it should work perfectly but again our problem you see that every time where we have to trigger some method of our widget we have to do this if check and you see we have only two concrete widgets so far but you can see how messy it looks like already and can you imagine if we have five or ten variants of the widgets so we have to find some better and flexible solution right so i would be satisfied with the solution when we would create some another abstraction layer which could be represented as some token as example and then somehow magically it would resolve the proper component instance for us and that's a good idea actually and we will implement exactly this but before to implement this before we start to build this abstraction layer we have to unify the public api of our concrete widget component so as you can see that our velocity component uses method load to load some data and our widget widget weather widget sorry uses the load data so we have to create some interface which unify the public uh public api for these concrete components so let's start with creating the our interface so i will call it widget interface interface dot ts and inside here i will export interface which i will call widget and inside this interface i will define the load method which is just a function which returns void yeah means nothing and then we have also refresh method all right which also returns void and now our velocity and weather widget should implement this interface so let's do it i will go to our velocity widget and i will add here implements widget widget interface yeah don't forget to import this here at the top and the same thing i will do for my weather widget if i will go to our weather widget and here we will do the similar thing then i have to import the widget and now it complains that we incorrectly implement the interface widget there should be a load method and because our load data does uh the same what should do load data we will just rename it and now uh the error is gone and now our component has the same public api so yeah i will save it also here now as i said earlier we have to create some token which will be working as our abstraction or breach you can name it as you want and i will create the new widget oh sorry new file inside the widget folder and i will name it like widget dot token dot yes right so and here inside that will be constant i have to export this constant the name will be widget and it will be the instance of injection token injection token for whatever reason autocomplete doesn't work for me so i will import manually so i have to import from angular chrome not core i believe and we import injection token and the value of this injection token will be some string i will call it also widget and we have to also define the type which will be which will contain this value so we say that we expect that the value of this injection token after resolving will be something some class instance which implements this uh interface we don't know which exactly class will be there either it will be uh whether component or velocity component we don't know we just know that will be instance of class which uh implements this load and refresh method that's actually everything what we have to know about this right and then we have to uh write this resolver so we have to do the next thing for every our concrete widget we have to provide this token so what we will do in providers we say that provide widget token and then we say that if some directive or class or whatever tries to access this widget please use existing instance of our class so weather widget component like this right so once we try to access this it will be resolved as an instance of our this weather widget component and of course the same thing we have to do for our velocity widget and i will just place it here and i have to import the token and i have to replace weather widget component with velocity widget because here we want to resolve it like this so we have to create reference to our velocity widget component all right that looks good the second thing we have to do is to adjust our uh wrapper component and now instead of uh trying to get reference to our concrete velocity widget component we will try to get access to our widget token which we created so like this and now it says that we can assign only component and directive but actually you can also do access of this injection token but you have to use uh this as any trick and with next angular release it will be fixed so you will be able to use it without uh this hack and then we have to replace our velocity widget component with our interface which we created as i said that we don't know which exactly uh instance will be here will be resolved we cannot do it just know that uh the there will be the implementation some class which implements our widget right so we can hopefully we should do it here and we can remove this part and also we can remove our weather widget also here and we don't need this check as well anymore then we can remove this part and this as well and now for the reason our dev server is down so i will restart okay it's there and now we can go to our widget and check if it's working yeah i can trigger the refresh for our weather component and now let's try to replace it with our velocity component i will save it try one more time yeah it was reloaded and i click refresh and we see that refresh mechanism was 2 years also for our velocity widget right and let's maybe create some other instances with different no uh different uh widgets inside and we can see now there are two like independent things which handle the refreshing independently and now let's try to recap this everything to get the complete picture and yeah we defined the velocity widget as example between this widget wrapper in widget wrapper we trying to get reference to the widget to our kind of bridge and this so we're trying to request this widget then it goes to the child inside in our case it's velocity widget and says hey uh do you have the widget yes i have so i have rejected this token so what the value of your token it says use my existing class instance so use uh this velocity widget component and then inside oops inside this widget wrapper inside this widget we get the reference of our velocity component and because we have the unified api we can call the load refresh and yeah we kind of our interface guaranteed that we have implemented this method and the similar happens for our app widget or sorry widget weather widget and we also in wrapper we go we try to access the widget in this case we have the weather widget so it go to weather widget and ask okay you have widget where the what the pointer of this widget and this is our instance of our widget component and inside inside our wrapper we get the instance of our weather component okay that was it for today i hope you enjoyed this video and i hope it was somehow clear for you because i know that this topic is kind of hard to understand however now we know everything to proceed with the complex material form field and we will build this in my next video so subscribe to this channel right now if you don't want to miss it leave your comments leave your feedback positive negative whatever and have a productive week and thank you for attention and see you in the future
Info
Channel: Decoded Frontend
Views: 19,490
Rating: undefined out of 5
Keywords: angular design patterns, angular patterns, angular design patterns and best practices, angular advanced tutorial, advanced angular tutorial, angular injection token, angular content projection, angular contentchild, angular tutorial, angular, tutorial
Id: 2rQOu9TmuxE
Channel Id: undefined
Length: 24min 34sec (1474 seconds)
Published: Sun Jul 19 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.