1 00:00:02,450 --> 00:00:06,100 So time for some inheritance and for a base class. 2 00:00:06,410 --> 00:00:12,380 I want to add a base class which basically has template element host element an element in it which 3 00:00:12,380 --> 00:00:18,440 does this job of selecting elements in the DOM which has the attach method which we always need ends 4 00:00:18,440 --> 00:00:25,230 on so which basically manages all these shared functionalities which our classes that actually render 5 00:00:25,230 --> 00:00:28,270 is something to the DOM have in common. 6 00:00:28,280 --> 00:00:33,680 So for that above my project input and also the project list class. 7 00:00:33,830 --> 00:00:38,270 So basically here I'll add the component base class. 8 00:00:38,270 --> 00:00:44,810 Now the name is up to you but I'll name it component because you might notice term from react or angular 9 00:00:44,840 --> 00:00:45,880 if you work with that. 10 00:00:45,920 --> 00:00:52,430 And even if you didn't work with that you can think of these classes as you will I user interface components 11 00:00:52,460 --> 00:00:58,760 which we rendered to the screen and every component is in the end a render arable object which has some 12 00:00:58,830 --> 00:01:04,970 functionalities that allow us to render it and then the concrete instances or the inherited classes 13 00:01:05,330 --> 00:01:10,340 add extra functionality which this specific component needs. 14 00:01:10,340 --> 00:01:14,230 So what goes into the general component class then. 15 00:01:14,420 --> 00:01:21,250 Well I would say these three elements for sure template element host element and element. 16 00:01:21,440 --> 00:01:28,010 Now we do have a problem here however regarding the types the template element will always be h HTML 17 00:01:28,010 --> 00:01:29,000 template element. 18 00:01:29,180 --> 00:01:31,980 But the host element doesn't always have to be a div. 19 00:01:32,030 --> 00:01:38,000 For example when we will add a project item class we'll render dead in a project list and not directly 20 00:01:38,000 --> 00:01:40,560 in our root div here. 21 00:01:40,610 --> 00:01:41,950 So that's not always a death. 22 00:01:42,440 --> 00:01:45,190 And this year well it's always an H to Al element. 23 00:01:45,200 --> 00:01:51,530 We can certainly settle on that but like in the case of the project input class we actually know that 24 00:01:51,530 --> 00:01:53,350 it's some more specific form of it. 25 00:01:53,360 --> 00:01:55,150 It's the HDL form element. 26 00:01:55,280 --> 00:02:01,700 So we would lose this extra information if we restrict ourselves to always having just an H2 html element 27 00:02:01,730 --> 00:02:05,240 there without storing more specific information. 28 00:02:05,270 --> 00:02:07,040 So how can we work around that. 29 00:02:07,730 --> 00:02:15,110 Well by not just using inheritance but by creating a generic class here where when we inherit from it 30 00:02:15,290 --> 00:02:22,640 we can set the concrete types for Dad we add angle brackets after the class name and then Q identifiers 31 00:02:22,640 --> 00:02:29,660 of our choice like t and you which would be common choices and now we also can add some constraints 32 00:02:29,660 --> 00:02:34,730 here and say that t will certainly be some kind of h t Mal element. 33 00:02:34,790 --> 00:02:41,120 It can be just an h t Mal element or a more specific word in orbit and the same is true for you. 34 00:02:41,960 --> 00:02:46,660 And then here we know the host element will be of type T and D element will be of type U. 35 00:02:46,730 --> 00:02:51,980 And now whenever we inherit from this class we can specify the concrete types sorted we can work with 36 00:02:51,980 --> 00:02:55,860 different types in different places where we inherit. 37 00:02:56,070 --> 00:03:03,220 Now let's all that a constructor here in that constructor we will need a little bit of information we 38 00:03:03,220 --> 00:03:09,910 need to know the I.D. of our template so that we know how to select it and that should be a string we 39 00:03:09,910 --> 00:03:13,050 need to know the host element I.D. which also needs to be a string. 40 00:03:13,090 --> 00:03:17,280 So did we know where to render this component. 41 00:03:17,490 --> 00:03:23,190 And I also want to get a new element I.D. So do we get an I.D. that has to be assigned to the newly 42 00:03:23,190 --> 00:03:24,380 rendered element. 43 00:03:24,390 --> 00:03:29,680 This however is optional which I signal by adding a question mark after the parameter. 44 00:03:29,730 --> 00:03:34,050 The alternative would be to also accept on the find here as a type. 45 00:03:34,050 --> 00:03:36,160 But I'll just use the question mark. 46 00:03:36,540 --> 00:03:45,500 And now with that in the constructor we can basically get this code here and put it into our constructor 47 00:03:45,500 --> 00:03:48,950 of the component class sort of restore the template element. 48 00:03:48,950 --> 00:03:55,220 But of course now the I.D. which we're getting here is that template I.D. which is why I'm getting this 49 00:03:55,460 --> 00:04:01,250 as our argument in the constructor and for the host element of the idea here of course is our host element 50 00:04:01,400 --> 00:04:10,670 ideas like this all is important of course regarding casting here we know this will be of type T because 51 00:04:10,670 --> 00:04:15,460 t here is this generic type which we store or which we use for our host element. 52 00:04:15,470 --> 00:04:23,290 So here we can cost it already and with that we're selecting elements we can all grab more code that 53 00:04:23,290 --> 00:04:30,080 code here where we import a node and so on and where we set the I.D. we can grab all of that. 54 00:04:30,180 --> 00:04:36,160 So let's copy that here and add this to the constructor of the component class as well imported node 55 00:04:36,400 --> 00:04:41,100 then we said element and element here has this generic type you. 56 00:04:41,110 --> 00:04:45,010 So when we cost here we know it will be that you type here. 57 00:04:45,010 --> 00:04:46,850 So we should cost it to you. 58 00:04:46,900 --> 00:04:54,280 That's a good use of generics here which makes this component class really reusable now regarding the 59 00:04:54,280 --> 00:04:54,830 I.D.. 60 00:04:55,240 --> 00:04:56,650 This is what we get here. 61 00:04:56,650 --> 00:05:01,780 The new element I.D. Now of course we might not always have this because it's optional. 62 00:05:02,200 --> 00:05:03,880 So we should check if we do have it. 63 00:05:03,910 --> 00:05:10,180 So if new element I.D. is a thing and only if it is a thing only then I will try to assign it otherwise 64 00:05:10,210 --> 00:05:16,280 we don't try it because then we have no I.D. to assign well with Dad we have the constructor. 65 00:05:16,360 --> 00:05:18,780 Now let's use the attach function here. 66 00:05:19,210 --> 00:05:27,280 So let's copy the attach method from one of our Robert classes and add it here as a private method in 67 00:05:27,280 --> 00:05:28,330 the component class 68 00:05:32,740 --> 00:05:38,590 we can then also call this attach at the end of the constructor of the component class. 69 00:05:38,590 --> 00:05:42,210 Now here we want to add an element but we don't know where it should be added. 70 00:05:42,610 --> 00:05:48,580 So that's actually some extra information we should fetch here as a form of argument than a constructor 71 00:05:49,120 --> 00:05:49,870 insert 72 00:05:52,390 --> 00:05:53,260 at start. 73 00:05:53,260 --> 00:05:59,710 Could be a name and that is a boolean let's say and we should move that in front of our optional parameter 74 00:06:00,070 --> 00:06:03,950 optional parameters should always be lost because people might omit them. 75 00:06:04,030 --> 00:06:10,510 You're required parameters start for can't come after these optional parameters and insert that START 76 00:06:10,510 --> 00:06:17,010 is then forwarded to attach their insert at beginning. 77 00:06:17,010 --> 00:06:18,720 You could also reuse insert at start. 78 00:06:18,730 --> 00:06:23,610 I'm just using a different name here to avoid confusion is received as a boolean. 79 00:06:23,610 --> 00:06:32,720 And then here we check if insert at beginning is true if it is then here we have ofter begin. 80 00:06:32,720 --> 00:06:42,710 Otherwise we have before end now we're flexible regarding how does gets inserted. 81 00:06:43,050 --> 00:06:49,570 I also want to mark this class now as an abstract class because people should never directly instantiated. 82 00:06:49,650 --> 00:06:52,440 Instead it should always be used for inheritance. 83 00:06:52,590 --> 00:06:56,110 So in front of class I add the abstract keyword. 84 00:06:56,130 --> 00:06:58,710 This makes sure that now we can't instantiate it. 85 00:06:58,800 --> 00:07:00,440 If we would tried to do so. 86 00:07:00,540 --> 00:07:01,790 Types could would yell at us. 87 00:07:04,140 --> 00:07:10,710 I will also add two more methods and let's see configure method and also then the render a content method 88 00:07:10,950 --> 00:07:16,260 and I will add it as an abstract method which means to concrete implementation is missing here. 89 00:07:18,000 --> 00:07:24,930 But we now basically force any class inheriting from component to add these two methods and to have 90 00:07:24,930 --> 00:07:30,450 them away lable I'm just adding this here so that if someone else looks at our code he or she can get 91 00:07:30,450 --> 00:07:36,270 a good understanding of what the idea behind the component clause is that it does all the general rendering 92 00:07:36,390 --> 00:07:41,700 or the attachment of the component but that the concrete content and configuration then needs to happen 93 00:07:41,700 --> 00:07:49,140 in the place where we inherit side note you can't have private abstract methods so private has to be 94 00:07:49,140 --> 00:07:49,670 admitted here. 95 00:07:49,700 --> 00:07:56,100 That's not allowed by typescript we'll end with this we can extend component here on the project list 96 00:07:56,670 --> 00:07:59,090 and now get rid of these free properties. 97 00:07:59,190 --> 00:08:03,500 We keep the assigned projects because that's specific to the project list. 98 00:08:03,570 --> 00:08:09,630 We also now want to specify the concrete values that should be locked in for our generic types. 99 00:08:09,630 --> 00:08:16,550 And we know if we revert this we know dead will have a h Tim Al Dave element and a h to element. 100 00:08:16,590 --> 00:08:24,390 So here I will pass in H Tim l div element and H Tim l element like this and then get rid of these free 101 00:08:24,390 --> 00:08:27,220 properties in the constructor. 102 00:08:27,240 --> 00:08:33,870 We now don't need dad here but instead we need to call super at the beginning to call the constructor 103 00:08:33,870 --> 00:08:39,480 of the base class and queue that we need to pass some information to the super constructor we need to 104 00:08:39,480 --> 00:08:40,760 pass some information. 105 00:08:40,890 --> 00:08:46,860 The idea of our template element the host element idea whether we want to insert this at the start of 106 00:08:46,860 --> 00:08:51,910 the host element and potentially the idea should be assigned to the new element. 107 00:08:51,970 --> 00:08:59,940 So here's our template idea and with that we can get rid of this here then here the host element that 108 00:08:59,940 --> 00:09:02,700 idea was app so we can get rid of this. 109 00:09:02,730 --> 00:09:06,240 We keep the assigned projects because we still need that here. 110 00:09:06,450 --> 00:09:16,020 We get rid of this year but regarding the idea for the new element I want to pass that as a fourth parameter 111 00:09:16,020 --> 00:09:16,740 actually. 112 00:09:16,890 --> 00:09:19,220 The third one is where this should be inserted. 113 00:09:19,260 --> 00:09:22,440 And here we used to insert this before the end. 114 00:09:22,440 --> 00:09:29,490 So actually what I want to insert here as a parameter for the insert at start value is false because 115 00:09:29,490 --> 00:09:35,910 it should not be inserted at the start but at the end. 116 00:09:36,050 --> 00:09:38,980 Now I certainly still want to set up my listener here. 117 00:09:38,990 --> 00:09:44,310 I don't need to call attached though that will happen in the base class and the base component. 118 00:09:44,470 --> 00:09:46,120 I will call render content though. 119 00:09:47,940 --> 00:09:54,410 And here we shouldn't use this type but just type because we can't use this before Super finished running. 120 00:09:54,450 --> 00:09:57,660 That's no problem though because we receive type as an argument. 121 00:09:57,720 --> 00:10:03,930 No you see I still get an error here because we have an attach method here in project list and that 122 00:10:03,930 --> 00:10:07,230 clashes with the attached method we have in the base class. 123 00:10:07,380 --> 00:10:10,500 So let's get rid of this attach method here. 124 00:10:10,650 --> 00:10:17,730 Now we still get an error because you see render content as private here but we specified as a public 125 00:10:17,730 --> 00:10:18,340 method here. 126 00:10:18,360 --> 00:10:23,820 I would love to have it as a private one but private abstract methods are not supported so I will remove 127 00:10:23,820 --> 00:10:30,120 the private keyword here and now is that we're left with one issue here that we're not having that configure 128 00:10:30,120 --> 00:10:32,040 method which have promised we have here. 129 00:10:32,040 --> 00:10:33,390 Well let's add it. 130 00:10:33,690 --> 00:10:40,260 So here besides render config we can add configure even though I'm not doing anything here. 131 00:10:40,590 --> 00:10:46,410 Alternatively you could convert this year to be an optional method by adding a question mark then you're 132 00:10:46,410 --> 00:10:53,510 not forced to add it here I will added Because we could also argue that we for the project list put 133 00:10:53,520 --> 00:11:00,420 Dad code where we set up our listener here actually into configure so we can reach out to configure 134 00:11:00,870 --> 00:11:03,170 and then do our thing here. 135 00:11:03,360 --> 00:11:09,840 That listener setup and now we should just make sure that we call render content but also configure 136 00:11:09,840 --> 00:11:17,240 like this in case you're wondering why I'm not calling configure and render a content here in the abstract 137 00:11:17,240 --> 00:11:18,590 class in the constructor. 138 00:11:18,590 --> 00:11:27,320 Well we could do this but we might have a problem that if we call this in the into component class then 139 00:11:27,350 --> 00:11:30,800 we might call a method in the inheriting class. 140 00:11:30,800 --> 00:11:37,520 So in a class that extends component we are render content or configure relies on something where the 141 00:11:37,550 --> 00:11:43,670 constructor of the inheriting class actually maybe set something up only after the base class constructor 142 00:11:43,670 --> 00:11:48,120 finished which render content and or configure rely on. 143 00:11:48,140 --> 00:11:54,200 That's why it's safer to basically make sure that the inheriting class has to call these methods instead 144 00:11:54,200 --> 00:11:58,030 of the base class calling these methods for us. 145 00:11:58,030 --> 00:12:04,060 So with that we restructured the project list class to take advantage of inheritance and of our shared 146 00:12:04,390 --> 00:12:05,060 logic. 147 00:12:05,090 --> 00:12:08,340 Let's do the same for Project input now there. 148 00:12:08,350 --> 00:12:17,380 We also want to extend component use the generic nature of that and there we have to age to meld Dave 149 00:12:17,440 --> 00:12:24,550 element for the host element and the HDL form element for the element which gets rendered with Dad we 150 00:12:24,550 --> 00:12:28,360 can get rid of these free properties here so let's do that. 151 00:12:28,360 --> 00:12:33,100 We keep these free properties of course because they're specific to project input. 152 00:12:33,100 --> 00:12:39,700 We then have to call super here and to super we pass these ideas off the template which is project input. 153 00:12:39,940 --> 00:12:44,160 The idea of the host element which is app insert before here is true. 154 00:12:44,170 --> 00:12:49,960 Because I want to insert that newly created element at the beginning here for this project input class 155 00:12:50,590 --> 00:12:52,930 and then a new element ideas. 156 00:12:53,140 --> 00:12:59,410 While that here is user input so we should all go forward debt was this we can get rid of this code 157 00:12:59,410 --> 00:13:00,320 of this code. 158 00:13:00,340 --> 00:13:05,290 And of all this code here actually of course keep this code here. 159 00:13:05,320 --> 00:13:09,900 However we could also argue that we put this into configure maybe. 160 00:13:09,910 --> 00:13:15,820 So let's go down to the configure method which we already have here and add our listeners here or our 161 00:13:15,820 --> 00:13:22,210 properties set up here to configure of course let's get rid of each attach because that's now something 162 00:13:22,210 --> 00:13:27,820 the base class does for us and let's check what types code doesn't like of course we should get rid 163 00:13:27,820 --> 00:13:29,340 of to attach here. 164 00:13:29,740 --> 00:13:36,220 And yeah actually one thing TIBCO doesn't like it now complains that these fields do not get initialized 165 00:13:36,220 --> 00:13:42,880 in the constructor because it doesn't understand or doesn't check that configure is called in a constructor 166 00:13:42,880 --> 00:13:44,600 and dust is initialization. 167 00:13:44,830 --> 00:13:51,250 So to satisfy typescript I'll actually move these initialization back from configure right into the 168 00:13:51,250 --> 00:13:52,210 constructor. 169 00:13:52,210 --> 00:13:58,240 Technically the result is exactly the same but now typescript won't complain it will complain however 170 00:13:58,270 --> 00:14:07,360 that we do have a private configure method so justice before we should change this and turn configure 171 00:14:07,360 --> 00:14:08,980 into a public method. 172 00:14:08,980 --> 00:14:13,720 Now it's not a must do but it's kind of convention to have your public methods first which is why I 173 00:14:13,720 --> 00:14:16,930 will move it up above the other private methods here. 174 00:14:17,320 --> 00:14:22,040 And of course now it also complains that we have no render a content method. 175 00:14:22,060 --> 00:14:28,150 Now I will add one just because we need to hear we're not doing anything in it so technically it's not 176 00:14:28,150 --> 00:14:37,980 required but now we satisfy our base class side note render content and configure in the project list 177 00:14:37,990 --> 00:14:44,160 class can also be moved above that private method here for the exact same reasons for this convention 178 00:14:44,170 --> 00:14:52,190 I just mentioned and with that we also restructured project input to take advantage of inheritance and 179 00:14:52,280 --> 00:14:52,950 let us D. 180 00:14:52,950 --> 00:14:55,100 Based class do a lot of the job. 181 00:14:55,370 --> 00:15:00,740 Let's see where dad now all works if we saved added compiles without errors. 182 00:15:00,740 --> 00:15:05,650 Seems to run fine so dust is work is the question. 183 00:15:05,930 --> 00:15:07,870 And Dad looks quite good. 184 00:15:07,880 --> 00:15:14,060 It works the same way as before but now we have cleaner code where we take advantage of code reuse which 185 00:15:14,270 --> 00:15:15,850 thanks to inheritance. 186 00:15:15,920 --> 00:15:18,310 Now it's not the only place where we can inherit. 187 00:15:18,620 --> 00:15:24,260 I want to conclude this lecture here by also refactoring our project state. 188 00:15:24,260 --> 00:15:29,570 Technically there we don't need inheritance because we only have this one single state we manage in 189 00:15:29,580 --> 00:15:31,050 his entire application. 190 00:15:31,250 --> 00:15:35,280 But imagine a bigger application where you have multiple different states. 191 00:15:35,330 --> 00:15:41,930 One Florida user state where the user is logged in and so on one for the projects one for a shopping 192 00:15:41,930 --> 00:15:43,060 cart. 193 00:15:43,070 --> 00:15:48,110 Now you will notice that some features of your state class are always the same. 194 00:15:48,140 --> 00:15:52,550 Specifically that array of listeners and to add listener method. 195 00:15:52,820 --> 00:15:55,470 So we could all use a base class here. 196 00:15:55,610 --> 00:16:03,530 We could use a class state here and that class has a listener's array and that class also has an add 197 00:16:03,530 --> 00:16:04,640 listeners method. 198 00:16:04,640 --> 00:16:09,050 So we'll cut both from Project state and add it to state. 199 00:16:09,200 --> 00:16:15,320 Now that also means that we of course don't know whether our listener will actually return an array 200 00:16:15,320 --> 00:16:16,760 of projects. 201 00:16:16,760 --> 00:16:25,770 So actually here for this function type I also want to have a generic type actually so that we can set 202 00:16:25,770 --> 00:16:27,220 this from outside. 203 00:16:27,500 --> 00:16:36,190 We can do that we can write a generic type like this here a custom type which is generic we can add 204 00:16:36,190 --> 00:16:38,370 the angle brackets after our type name. 205 00:16:38,460 --> 00:16:42,480 Use an identifier of our choice and then reuse that type here. 206 00:16:42,490 --> 00:16:48,250 Now we can make state generic we can use the same identifier because it's a different construct than 207 00:16:48,250 --> 00:16:49,720 our custom type. 208 00:16:49,720 --> 00:16:57,130 And then here when we say that we want to have a list of listeners we have to tell typescript which 209 00:16:57,130 --> 00:17:01,690 generic type the listeners use for this state object we're creating. 210 00:17:01,690 --> 00:17:08,320 And that simply means we can forward our generic type here and here someone we now extend state we have 211 00:17:08,320 --> 00:17:10,360 to specify the type of data. 212 00:17:10,360 --> 00:17:16,500 This state will work with and instead of states this then gets forwarded to our listener custom type. 213 00:17:16,510 --> 00:17:17,690 That's the idea. 214 00:17:17,690 --> 00:17:19,420 Now how do we use all of that. 215 00:17:19,630 --> 00:17:26,830 Well down there in the project state class we simply extend the state class and now provide a value 216 00:17:26,830 --> 00:17:30,060 a concrete value for that generic place holder. 217 00:17:30,130 --> 00:17:35,850 And here this concrete value is project because this project state is all about managing. 218 00:17:35,860 --> 00:17:44,070 Guess what projects now the private constructor here has a problem as you can tell because we're not 219 00:17:44,070 --> 00:17:46,960 calling Super while we should definitely do that. 220 00:17:46,980 --> 00:17:48,380 Let's call super in here. 221 00:17:48,390 --> 00:17:56,700 That's all we got to do their end here if we scroll down where we go through the listeners we see listeners 222 00:17:56,700 --> 00:18:00,300 as private and it's private and our base class. 223 00:18:00,300 --> 00:18:06,510 Now that means we can only access it from inside the base class but you learned about a no access modifier 224 00:18:06,810 --> 00:18:15,500 which is similar to private but also allows access from inheriting classes that would be protected protected 225 00:18:15,510 --> 00:18:22,080 means it still can't be accessed from outside the class but it can be accessed from any class that inherits 226 00:18:23,060 --> 00:18:23,590 with Dad. 227 00:18:23,600 --> 00:18:30,290 Let's save all that should compile just fine and let's quickly test this and that's looking good so 228 00:18:30,290 --> 00:18:30,820 that works. 229 00:18:30,830 --> 00:18:34,090 Ask before but now again with a bit nicer code. 230 00:18:34,220 --> 00:18:38,210 Using inheritance and generics also for our estate management.