Custom Angular Schematics — Generating Custom Component (advanced)

Custom Angular Schematics — Generating Custom Component (advanced)


Custom Angular Schematics — Generating Custom Component (advanced)

In this video, we will continue to explore angular schematics and I am going to show you have to create a schematic that will generate a custom component for you with an already pre-injected Angular service. This video is an extension of the previous one where we were implementing the ng-add schematic. I hope you will learn something new today and please enjoy the video.

💥 Angular courses made by Dmytro - https://bit.ly/df-courses 💥
✂️ Use coupon YOUTUBE_DISCOUNT to get a 10%-off discount ✂️

🕒 Time Codes:
00:00:00 - Intro;
00:01:04 - Quick walk through the project;
00:04:23 - Implementing the schematics to generate a custom component;
00:07:56 - What is Schematic Schema;
00:11:57 - Define an interface for options;
00:13:00 - Implementing factory function for the schematics;
00:15:44 - About Schematics Templates;
00:21:37 - Continue work on Schematic factory function;
00:34:08 - How to reuse existing schematics;
00:40:06 - Outro;

Link to the Project on GitHub:
https://github.com/DMezhenskyi/ngx-sc

More about Schematics on Angular Docs:
https://angular.io/guide/schematics-f

↙️ Short Frontend Snacks every week here:

Twitter - https://twitter.com/DecodedFrontend
Instagram - https://www.instagram.com/decodedfron
LinkedIn - https://www.linkedin.com/in/dmezhenskyi

#angular #webdevelopment #schematics #ng


Content

4.48 -> Hey everyone! Welcome, my name is Dmytro  Mezhenskyi and today we continue our talk about  
10.4 -> Angular schematics. My internal YouTube statistics  shows that you like my previous video where we  
19.2 -> were implementing ng-add schematics so this is  the schematic that is being executed when we  
26.32 -> add some certain library to the project to the  angular project via ng at command uh and i saw um  
36.88 -> high activity under this video so i decided to  continue and in this video i will show you how  
43.44 -> to create another schematic that allows you to  generate some custom component let's say the  
51.36 -> component with already injected some service so  this is what we going to implement in this video  
60.16 -> so i would suggest you to get started right now  all right first of all let's quickly recap what we  
69.12 -> have done in the previous video if you forgot if  you have not seen it please check this out first  
76 -> one more time because it most probably you will  not really understand what is going on here  
84 -> but for those who have seen it let's quickly  walk through so we created an angular workspace  
91.44 -> and we created some empty angular library  using these two awesome commands and  
99.12 -> then we created a schematics folder in the root of  the library uh don't be confused not the root of  
107.44 -> the workspace root of the library uh there we  created schematics folder and there inside we  
114 -> created a collection json file where we described  the list of supported direct oh directive sorry  
124.16 -> schematics and there is only one so far it  is ng add this is the schematic that is being  
133.04 -> activated when we add our library to the project  using ng add command and what is happening here  
143.04 -> once we add this library to the project  uh angular cli looks for the factory  
151.52 -> key within this collection json file and then it  tells that our schematic the script that has to  
158.8 -> be executed located under the ng add folder right  there and inside the index dl or js file there is  
168.4 -> a ng add function uh that will be kind of uh  called in order to create our schematics and  
178.56 -> we indeed have this index ds file and there inside  we have our factory function ng-add that will be  
186.56 -> called and this whole thing will happen and in the  end we'll update our app model ts file and we will  
198.56 -> set up our library we add to the imports  array our library model and everything  
206.24 -> will be working fine and we uh deploy our  or better to say we publish our library  
215.04 -> to the local npm registry for that i'm using  ferdaccio and you can see that uh i'm running  
222.88 -> it locally right here so let's switch to the  terminal and this is basically it so now i  
230 -> hope we record everything and there's no there  are no questions of what is going on there i as  
238.4 -> i said in the intro in this video we're going to  create another schematics that will be generating  
246.48 -> some custom component um this component should  have already injected in the constructor the  
257.28 -> uh service that comes from our super ui library  and yeah let's get started and let's get started  
266 -> from the collection json file will we are going  to introduce a new schematics right there and  
275.2 -> i will name this schematic like super ui component  they should describe also what this schematic is  
285.84 -> going to do so we need a description so i'm  gonna say this schematic generates super  
294.96 -> component like that awesome the next property we  have to add is obviously factory so factory is  
305.36 -> going to be located under the super ui component  folder and there will be index file and we're  
314.64 -> gonna trigger the function that i'm going to  name super ui component generator here we go  
324.4 -> and now because our new schematic will be getting  some options like we're going to provide the name  
334.16 -> for the component right we're going to provide  a path where should be created this component so  
340.88 -> we didn't have this for ng at schematic  but here we need it and in order to  
350.64 -> achieve this we have to describe the  schema for the schematic describe the  
357.2 -> options that we're going to uh get from the  user input when they will type ng generate  
364.48 -> uh blah blah super ui component and so on so  that's why we have to introduce a new property  
372.16 -> called schema and definitely we have to provide  a path to this file and it's going to be also  
380.24 -> under this super ui component folder and i  call it schema and it is json file here we  
390.24 -> go and let's maybe add some fancy stuff why  not uh and i would suggest you to provide some  
399.28 -> shortcut as example if you use ngcli  you know that instead of writing uh ng  
407.68 -> generate component and so on you can just type  ng g component c for component and then some  
416.72 -> name whatever you like so we will do the similar  thing for this schematic as well and there is the  
426.16 -> property for that it is called aliases and there  inside the array we can define some shortcuts in  
436.08 -> my case it will be uh let's use first letters  from here from here from here so it will be  
444 -> suk suk or sak doesn't matter uh all right i think  it would be enough so we have everything uh and  
455.76 -> now let's create appropriate files and folders so  let's start with the factory i'm going to create a  
463.52 -> new folder called super ui component then we will  create a new file it is going to be index index ts  
474 -> and also let's close it and also we have to create  a schema right so let's create it also next to  
484.56 -> index ts file schema json in this file you should  add content like that all right and here for the  
494.8 -> schema key we have to provide this string uh for  id we should provide some id in my case it's going  
502.48 -> to be a super ui component and also i need some  title for this schema let's say it is a super  
511.92 -> ui library component schema here we go then we say  that it's going to be type of object and as every  
523.52 -> object it has properties and here we describe  already properties that we are going to provide  
531.92 -> so those are flags that we are providing when  we do um if you know ng generate component then  
540.72 -> my uh component and then we provide some  module and then many other options so  
547.52 -> those are these properties basically all right  so let's add a few of them i would suggest you  
556 -> to have a name in order to provide the name of  the component right so it's going to be name  
563.36 -> then we also have to provide a  description that explains what uh  
570.08 -> this property is responsible for in our case it  is the name of the component and then we should  
579.92 -> define the type of this property and the type  of this property i would say it is a string  
590.88 -> cool for now i would say it is enough we can  go forward and introduce a new uh property and  
600.08 -> it's going to be the path so means where in our  file system we should create this component right  
608.56 -> and i would say that um okay yeah let's add the  description of course so where should be created  
619.76 -> the file okay and then we have to define also  the type the type is going to be string as well  
632.4 -> then we have to format it and format it to the  path so it will be the proper path for uh to the  
642.64 -> folder and um let's add also some fancy stuff and  namely xprompt it's um when you run the schematic  
655.52 -> it will stop the execution and it will ask you to  type some value before uh the execution um will  
665.04 -> continue you will see it in action no worries  but so far let's say x prompt and we have to  
674.48 -> provide the message that should be displayed right  above the input field so we can actually copy  
685.04 -> this message and just add question mark um  and the last property is let's say it's uh  
696.96 -> default so we can provide some default value  right why not so the default value can be  
706 -> source app so let it be there and i think  we are pretty much done so i can save it
718.08 -> so these properties will be passed to our factory  function and i would suggest you before we start  
728.64 -> to use these options we have to create some  interface and describe those options so we  
736.08 -> have uh strict types intellisense and all these  fancy things that uh typescript give us so i will  
747.76 -> create a new file called super component dot ts  and here i'm going to export export interface  
761.2 -> super ui components schema like that and we have  two properties their name that is string and we  
773.68 -> also have a path that is also string that's  it so now we can uh continue and write our  
786.64 -> factory function how did i name this factory  function aha it's going to be super ui component  
795.76 -> generator all right so export function super  ui generator and it's going to return another  
807.92 -> function all right so if you remember we got here  the tree and schematic context parameters right  
818.24 -> but you we don't need for this particular case  those stuff so i leave it blank if you want to  
827.52 -> check what is actually taking this function you  can check it right there so but i will close it  
835.76 -> uh we're going to return the rule and rule  comes um okay autocomplete doesn't work um  
845.84 -> i think uh i think i can fix it no it doesn't  work um i could fix it if i install npm  
857.36 -> install angular dev kit schematics and save it  as a dev dependency i think it works because  
868.64 -> angular dev kit is dependency for some and  other dependencies so it was installed but  
873.84 -> uh we have to explicitly install it in order  to have this uh autocomplete i think someone  
881.6 -> left the comment under the first video he was  complaining to uh something similar i believe  
889.44 -> his issue was caused by those stuff all right  now we can see the intellisense and i can use it  
900.16 -> and add automatically the rule the import uh  and import the rule from devkit schematics  
908.72 -> cool uh then options yeah options that we  provide here we can get the access to them  
919.44 -> uh as an argument for our factory function so  they will come there and how do they call it super  
929.84 -> ui component schema okay let's import it  very very good start and uh let's write the  
941.44 -> logic for our uh factory function and  here the interesting things are coming so  
949.6 -> um i'm going to introduce a new constant and what  should we add to this constant if you remember in  
958.72 -> the previous video we created the file and  there we then we did what we add edit import  
966.72 -> to the module things like that but in our case  we we are going to create the whole component  
975.2 -> yeah we want to add a lot of stuff and it  would be difficult to write this everything
985.2 -> to write all those stuff so it would be really  cool if we could use some template for that  
993.84 -> right and angular schematics allows us to do this  so we can create template files and replace just  
1004.08 -> some you know some stuff with variables with the  options that we getting from the user input and  
1014 -> let's create such a file i'm going to  create it in this super ui component  
1021.52 -> folder so i will name it files and here i have  to create a new file but please pay attention  
1032.24 -> on the naming how we have to name  it it starts with two underscores  
1040.08 -> then we have to say name and this name should  match the name of the property that we're going  
1051.2 -> to provide that we described in our schema right  so uh it would this name will be replaced with  
1058.56 -> the actual value that user will provide to  us then you have to use add sign and after  
1067.36 -> add sign you define the method that will  be applied to the name and that will  
1077.76 -> take the string and dasherize this means that  if you get the name in the comment case it will  
1085.04 -> be replaced to the dashed version and how you can  do this you can write dash arrives and two times  
1095.6 -> underscore again about these functions like  dasherize we will talk in few minutes i will  
1105.84 -> show you how you apply them to the template uh  where they come from but so far like yeah it it  
1113.36 -> should be like that then after that we press dot  and then component dot ts and then dot template  
1125.12 -> this is the file we have to create inside  this template we should uh provide some code  
1135.2 -> right so i will take some regular uh  component from from here so i just copied and  
1145.28 -> pasted then i would add a new import and namely  i'm going to import the super ui library service  
1158.24 -> and it comes from super ui library all right  so i will remove styles and we have to adjust  
1170.88 -> naming and here we will use again this dasherize  and classify uh function helpers namely we're  
1182.16 -> going to replace the selector first and here we're  going to use the next construction like that then  
1192.24 -> two times uh percent sign and uh then it should be  equal sign and here we should provide some value  
1203.36 -> like name but we don't know what kind of format  will be there if it's camel case or something else  
1212.64 -> so to be sure that it will be dasherize  we we're going to apply uh this dasherize  
1220.48 -> function and i will do it like that pressurize  and is a function so we have to do it like  
1228.8 -> that cool then we go to the template and we have  to replace uh this string as well so i will reuse  
1239.68 -> this part and replace this hard coded stuff and  maybe let's make it in one line to save some space  
1248.56 -> and here we have to also replace this sub ui  leap prefix with something dynamic so we will  
1257.52 -> replace it with a name as well but we want to use  camelcase there right and there is the another  
1265.2 -> helper function called classify like that cool  and then as i said in the very very beginning  
1275.2 -> we have to automatically inject uh the super ui  ellipse service so we will do it right here so  
1284.88 -> it's going to be private super ui service  and it is super ui leap service instance  
1297.28 -> cool we are done with the template i hope  we forgot nothing so i can save it and then  
1306 -> we have to use this template somehow inside  our factory function so i'm going to close it  
1314.4 -> and yeah i introduced the constant and i'm  going to name it now well template source and to  
1325.36 -> this file to this template we just created  we have to apply our options we have to apply  
1334.88 -> our functions that we are using right here  right and in order to do this we have to use  
1343.6 -> the helper function called apply and it comes  from also dev kits schematics and this function  
1354 -> takes couple of arguments it takes source and  array of rules and the source it is basically our  
1365.76 -> template to create this source we also have a  helper function called url that also comes from  
1372.96 -> schematics and this url takes uh the string that  leads to our files and the second parameter it  
1382.96 -> is an array of rules what kind of rules we'll  see in a second so the first rule we have to  
1390.08 -> as i said apply uh all options all functions  to this template and there is a special helper  
1399.12 -> function apply templates and this function  takes an object where we provide options and  
1408.88 -> functions so we have to provide basically classify  function dasherize function and we have to provide  
1416.72 -> the variable name so here i say that for classify  we should provide some function and there is such  
1424.8 -> a function already created we just have to  import it from the dev kit core it leaves  
1432.64 -> as i said inside the core and there is an  object called strings and inside the strings  
1440.48 -> we have classify method you can see  there are a lot of them they can analyze  
1447.36 -> uh format to underscore format caramelize  capitalize and use whatever you like but  
1455.92 -> for my particular case classify is the proper  option then we have to provide dasherize function  
1465.36 -> so for dasherize i will grab it here make sure  that this function should match the object key  
1474.64 -> so keep in mind that and also from strings i have  dasherize function as well and what is reminding  
1483.92 -> else there is a mining name variable and we will  also provide it right here and it comes from  
1493.92 -> our option or better let's say it has options yeah  options and name here we go that's it so this rule  
1506.48 -> uh as i said we'll apply all those stuff to our  template and then once we have everything applied  
1513.2 -> what we have to do we have to move this into the  proper destination because we have also the path  
1521.76 -> property right in order to do this we have also  dedicated function that is called move and it also  
1529.84 -> comes from the schematics and as argument it takes  the string where eventually our file should be  
1538 -> created right and let's provide such a string so  we will use the option path right and then if you  
1548.88 -> remember that angular cli by default they create a  separate folder uh with the component name and put  
1560.16 -> all the files inside that folder so we can create  such a folder as well so i will again uh use uh  
1569.6 -> use dasherize function from strings and there  i will provide i will provide the options name  
1580.64 -> and basically it looks okay but there is a  small issue because if you work on the windows  
1588.32 -> this path will be probably not relevant because in  windows you have to use forward slash like that so  
1597.12 -> uh we can normalize it we can adjust it and  there is a function for it called normalize and  
1606.16 -> this function comes from a dev kit core as well  so i will import it right there make sure that  
1615.2 -> it is being imported from the dev kit core and  it is a function so we have to wrap our string  
1625.12 -> like that and here we go our template  source is ready now now we have to return  
1633.44 -> only something from our factory function  right so uh let me make it smaller  
1640.48 -> what we are going to return and we're  going to return such a thing called  
1647.2 -> chain like that and this chain takes an array  as an argument and it returns actually it takes  
1657.6 -> rules multiple rules that needs to be applied  in this chain and return the one or the kind of  
1665.6 -> merged rule so to say and i did it intentionally  i will show you later one we why we would need  
1675.12 -> the chain but so far let's use only  uh one rule and it's called mergeus  
1685.04 -> and it takes as a argument you can see expect the  source and we have this source actually so this  
1692.64 -> is this one i provided and we are pretty much  done yeah we can actually save it and we could  
1702 -> try uh to build our schematic and  publish our library and check if this uh  
1710.32 -> very basic implementation is working so i just  make sure that i saved everything and we have to  
1720.4 -> we have to increment the library version from our  package.json file so i'm gonna say that it's going  
1729.28 -> to be version four and now we have to build the  library so i'm going to build the library itself  
1738.32 -> first and then if you remember we have to build  separately the schematic itself because we have  
1745.92 -> uh typescript files we have to compile  this everything and move appropriate files  
1753.28 -> and by the way we have to also adjust our this  post build script that it's good that i opened  
1762.24 -> this package file because i forgot to adjust  this we have to actually add uh the following  
1769.04 -> lines so we also have to grab all schemas that we  uh created right here and also we have to grab all  
1778.64 -> files means all our templates and we should  also copy it to the uh this folder for of our  
1787.28 -> library so we have to publish it as well so this  is very important step so i can save this part  
1797.6 -> and yeah as i said we build the library first now  we have to build the schematic and i'm going to  
1808.24 -> run also npm build command but with this prefix i  say that run the build command for the packet json  
1818.24 -> that lives in the library root not in the root of  the workspace itself so uh such a way we're going  
1825.92 -> to build the schematic you can see that files  were copied successfully we have to find it  
1834.48 -> there as well so there is our super  ui component files everything looks  
1840.88 -> pretty well so we are ready to publish it  so i'm going to navigate to this and then  
1848.56 -> super ui library and i'm doing to npm publish  here we go my uh new version has been added  
1858.24 -> to the local npm registry and now i can go  to the project i just created this is just  
1867.6 -> simple angular application i created with ngnu  command and now let's try to type ng at super ui  
1876.24 -> library and i defined the registry where i have  to pull this library because i'm losing ferdacho  
1883.36 -> locally and i have to provide this parameter to  say that please pull this library from the local  
1892.72 -> npm registry cool so i'm running this command  and you can see that ngat schematic has been like  
1901.44 -> hooked right so i say that yes i want to execute  ngat schematic and you can see it in action so it  
1909.6 -> updates my uh app model ts file you can see and it  was added right there so this is ngat schematic in  
1919.84 -> action and now we want to run our new one and  how we do this we type ng generate and then we  
1927.84 -> have to provide the name of the library so it's  a super ui leap and after column we have to say  
1936.32 -> which exactly schematic has to be involved and  we named our schematic like super ui component  
1946.56 -> like that and we have to provide some name yeah  this is the name we described in our schema right  
1954.96 -> here uh this is this parameter and i will call  it decoded front end all right cool and now i can  
1967.36 -> run this command and now you can see this where  should be created the file so this is exactly  
1976.24 -> uh this x prompt property in action uh so it  and also you can see that uh default value has  
1985.84 -> been highlighted right here so we can leave it as  it is or you can provide some string like super  
1995.68 -> compo nens like that and now i press enter and my  my schematic has been executed you can see that  
2005.28 -> my super component has been created and let's have  a look what is inside and um we have the component  
2015.84 -> with a proper selector with the super ui service  injected everything looks really super super cool  
2026 -> however let's do one more step further what the  problem currently the problem currently is that um  
2037.12 -> oh it was created in the wrong all right i had  to type source app and then super component so  
2044.24 -> it was created in there in the root of the source  folder but okay it doesn't matter um the problem  
2050.96 -> is that we created just a component but component  usually consists from template it consists from  
2057.84 -> styles it consists from unit tests so usually  we have four files for one single component  
2065.84 -> and should we create them from kind of from from  scratch should we create other files separately  
2076.8 -> for every four styles for component view and so on  we could do this but why if we can reuse already  
2089.04 -> existing schematic that does exactly what we need  so let's reuse the schematic that default for  
2097.36 -> angular and if you want to do that in this chain  of rules we have to introduce the new rule and  
2107.28 -> there is a function for that called extern  external schematic and it is a function  
2116.16 -> that takes two arguments uh the first one is a  string which exactly schematic should be executed  
2125.2 -> should be taken and it is schematics angular then  we have to say that uh which exactly schematic  
2138.48 -> name should be uh taken and we say  that in our case it is a component  
2145.28 -> right so we should reuse component generator  basically right and the third option  
2155.12 -> is options that are provided from the user so  basically this is uh those options so i can  
2165.28 -> copy them and provide it that's it the only  reminding thing is here when we merge together  
2175.84 -> those two rules we have to define how  it should be merged some merge strategy  
2184.16 -> and there is such a merged strategy and  we say that uh we would use override  
2192.72 -> strategy you can check there are a few of them  you can read about them more but to be honest i  
2200.16 -> don't know all of them i know just few of them  like override this is what i'm going to use  
2207.2 -> uh so um it says that if there will be conflict  if we if we are trying to create uh two  
2215.92 -> ex two same files and there will be overlap  because there will be we are creating a component  
2222.48 -> file and uh schematics angular component will  create uh also the file but we want to override  
2230.56 -> this file with uh with our component all right  so that's why we have to use this merge strategy  
2239.2 -> and keep in mind it is not merging the content  itself it's um overriding of the file and this  
2249.6 -> is pretty much it i will save it and then i will  navigate to the project root and i have to build  
2261.92 -> only schematics i believe i know i have to also  increase the package version so it's going to be  
2271.68 -> uh version 005 so i'm saving it then i  run i build the library then i'm going to  
2282.96 -> build the schematics itself and now i go to the  this super ui and run npm publish one more time  
2296.64 -> the fifth version has been uh added deployed  and now let's maybe revert all those stuff we  
2306.4 -> can also clean it up and uninstall our library so  we will do everything from you know from the very  
2313.84 -> beginning and then i'm going to add this library  using ng add here we go and now i'm going to  
2323.04 -> create another super ui component uh again with  the name decoded front end i press enter uh then  
2333.52 -> let's type this time proper uh path name so  it's going to be source app super components
2345.12 -> and you can see that we created four files uh also  this angular schematic default schematic updated  
2356.56 -> app model for us and it has added our component  right here it created besides the component itself  
2365.76 -> it created for us the styles file it created the  html file for the view spec files and also if we  
2377.12 -> have a look at the component you can see that  there we have the component that we defined in  
2385.36 -> our uh template file you can see that service has  been injected like everything as we wanted to have  
2395.28 -> but additionally we got those additional uh  files from the default angular schematic yeah  
2405.04 -> it is just so cool all right guys that was it  i hope you enjoyed this video and i hope you  
2411.28 -> learned something new today something what  you can already apply in your daily work  
2418.16 -> and if it's so please share this video with your  colleagues and friends use your social media  
2424.88 -> twitter linkedin and so on don't forget to drop  your comments as well because i would like to know  
2431.2 -> your opinion your opinion about schematics about  all my videos maybe have some suggestions drop  
2440.16 -> everything right there i read every comment  and try to answer when i have time besides that  
2447.76 -> don't forget that i have some video courses  you can check them out following this link  
2454.24 -> and it is a great option to support my channel and  in return i promise you some cool knowledge that  
2461.92 -> can help you to stand out and warn your colleagues  and this is everything i wanted to mention  
2469.52 -> i wish you product week ahead stay  safe and see you in the next video
2481.2 -> you

Source: https://www.youtube.com/watch?v=dADWO1Wh6-4