Coding

Angular Elements Introduction & Walkthrough

  • 00:00:01 in this video we'll do just that we'll
  • 00:00:04 load an angular component well this
  • 00:00:06 would be pretty boring so we'll do it an
  • 00:00:08 exciting way we'll load it dynamically
  • 00:00:11 as a custom element as a native web
  • 00:00:15 component instead of a normal angular
  • 00:00:18 component what's great about that and
  • 00:00:20 how does it work let's take a closer
  • 00:00:22 look at this in this video
  • 00:00:27 so let's get started with angular
  • 00:00:28 elements what is angular elements it's a
  • 00:00:32 feature of the angular framework that
  • 00:00:34 allows you to turn your normal angular
  • 00:00:36 components which you use in your angular
  • 00:00:38 app into native web components web
  • 00:00:42 components are basically custom HTML
  • 00:00:43 elements you could say they are part of
  • 00:00:46 the of the Dom of the JavaScript API
  • 00:00:48 they're not related to angular and you
  • 00:00:51 can use them in vanilla JavaScript apps
  • 00:00:53 or it apps built with other frameworks
  • 00:00:55 so that's web components and that is
  • 00:00:57 what you can create with angular
  • 00:00:59 elements now before you get too excited
  • 00:01:03 right now at the point of time I'm
  • 00:01:05 releasing this video when angular 6 was
  • 00:01:07 released the web components you're
  • 00:01:10 building with angular can only be used
  • 00:01:12 an angular project still and the obvious
  • 00:01:14 question then is why would you build web
  • 00:01:17 components at all what is the use of
  • 00:01:19 angular elements if you can only use
  • 00:01:21 these elements inside of an angular app
  • 00:01:24 and the answer is they are useful for
  • 00:01:27 loading dynamic content so let's say you
  • 00:01:31 got a content management system on your
  • 00:01:33 back-end on a server and there your
  • 00:01:36 editors can create HTML code they know
  • 00:01:39 how to write HTML code and therefore
  • 00:01:41 they create the content that gets loaded
  • 00:01:44 into your angular app in HTML now so far
  • 00:01:48 that is fine but what if you actually
  • 00:01:50 want to enable them to also use some of
  • 00:01:53 your angular components in the HTML code
  • 00:01:55 they prepared if they do that if they
  • 00:01:59 use your angular component selectors and
  • 00:02:01 you then load this content dynamically
  • 00:02:03 in your angular app it will actually not
  • 00:02:06 work because your angular app is
  • 00:02:08 compiled ahead of time or even with
  • 00:02:10 just-in-time compilation it's compiled
  • 00:02:13 before the content is loaded so if the
  • 00:02:15 content contains these Elector of an
  • 00:02:18 angular element of an angular component
  • 00:02:20 this will not work it will not recognize
  • 00:02:22 that let me show you what I mean here's
  • 00:02:25 a brand new angular project read with
  • 00:02:28 the angular CLI important if we check
  • 00:02:31 the package to JSON file I'm using
  • 00:02:33 angular version 6 and I'm using rxjs
  • 00:02:36 version 6 and I installed the rxjs
  • 00:02:39 compat pack
  • 00:02:40 to have no issues with rxjs this might
  • 00:02:43 be needed at the point of time recording
  • 00:02:45 this I need it for the angular elements
  • 00:02:47 package which we'll use in the future
  • 00:02:49 you might not need this all angular
  • 00:02:51 packages should by default support the
  • 00:02:54 rxjs syntax if you want to learn more
  • 00:02:56 about what changed with angular 6 and
  • 00:02:58 why does rxjs six thing is so important
  • 00:03:01 check out these separate videos I
  • 00:03:03 created on that my angular 6 update
  • 00:03:05 video and the rxjs six update video but
  • 00:03:08 back to the angular components let's
  • 00:03:10 create a new component let's name it
  • 00:03:12 alert component maybe a normal angular
  • 00:03:14 component so in there I'll export a
  • 00:03:16 class alert component like this and of
  • 00:03:20 course we could create that with the CLI
  • 00:03:22 too
  • 00:03:23 I'll import the component decorator and
  • 00:03:25 in there I'll define my selector which
  • 00:03:27 is Apple eart let's say and a template
  • 00:03:30 which could to be of course an external
  • 00:03:33 file – but here I'll simply add a div
  • 00:03:36 and inside of the div I'll say this is
  • 00:03:39 an alert and then we all even output a
  • 00:03:43 message here so some string
  • 00:03:44 interpolation now last but not least
  • 00:03:46 I'll add my Styles array here with a
  • 00:03:49 string in there to define some styles
  • 00:03:52 for this template and there I simply
  • 00:03:55 want to star my div give it a border of
  • 00:03:57 1 pixel solid and black background of
  • 00:04:01 let's say Selman so this is a light red
  • 00:04:06 color and a padding of 10 pixels and
  • 00:04:09 last but not least let me also define a
  • 00:04:13 font family and Selman by the way should
  • 00:04:16 not be a string let me define a fun
  • 00:04:18 family of sense serif
  • 00:04:20 now this is my my style for D for the
  • 00:04:23 alert now the alert uses this message
  • 00:04:26 property so I have to add it here and I
  • 00:04:29 want to make this bindable from outside
  • 00:04:31 salt decorated with at input which I
  • 00:04:34 have to import from angular core and now
  • 00:04:37 with that D component is finished and we
  • 00:04:39 can now use it to use it we have to add
  • 00:04:42 it to our declarations array there I add
  • 00:04:44 my alert component and with it added
  • 00:04:48 here we can go to the app component to
  • 00:04:51 its HTML file to be precise and then
  • 00:04:53 we can use my newly created app alerts
  • 00:04:56 component like this and of course all
  • 00:04:58 the pass a match the message which since
  • 00:05:01 it's a string can be passed like this
  • 00:05:02 without the square brackets this is just
  • 00:05:05 a shortcut in case you are passing some
  • 00:05:06 text and there I could say this is a
  • 00:05:09 normal angular component with that if we
  • 00:05:14 save all these files and we go back we
  • 00:05:16 see our component there now the styling
  • 00:05:19 didn't work yeah I should add more
  • 00:05:24 semicolons instead of commas with that
  • 00:05:28 now we got this alert so there's a
  • 00:05:31 normal angular component now let's say
  • 00:05:33 in the app component we actually want to
  • 00:05:35 load this dynamically I got this content
  • 00:05:37 property there it's null initially and
  • 00:05:40 now let's say instead of outputting this
  • 00:05:42 component like this we have a div and on
  • 00:05:46 this div we use the inner HTML property
  • 00:05:50 binding to bind to you the content in
  • 00:05:53 the app component in the constructor for
  • 00:05:56 simplicity reasons I can then add my
  • 00:05:59 timeout just to simulate that this is an
  • 00:06:02 asynchronous task and we're getting this
  • 00:06:03 from a server we don't have to put it
  • 00:06:05 into a timeout we can also run this code
  • 00:06:07 once does Epke port loads just adding
  • 00:06:10 this to well give us a little bit of
  • 00:06:11 time to prepare for the data to arrive I
  • 00:06:13 guess and then that function that
  • 00:06:15 executes here in set timeout I now want
  • 00:06:18 to set this content to let's say a
  • 00:06:19 string that holds HTML paragraph so this
  • 00:06:24 is all obviously not using our element I
  • 00:06:27 just want you to show you that this
  • 00:06:28 works we're now rendering this paragraph
  • 00:06:31 if we inspect it we see a paragraph is
  • 00:06:33 rendered to the Dom because we're using
  • 00:06:35 inner HTML now what be great if we could
  • 00:06:39 use our own element there so if we could
  • 00:06:41 use app alert here like this app alert
  • 00:06:45 and now we also set a message of
  • 00:06:50 rendered dynamically dynamically because
  • 00:06:54 we don't include it in our component
  • 00:06:57 template we're not including it in the
  • 00:06:59 app component HTML file but here we're
  • 00:07:02 hard-coding an intro record but we could
  • 00:07:04 easily imagine that this is coming from
  • 00:07:06 an API
  • 00:07:07 KOB that were fetching this from a
  • 00:07:08 server so if we do it like this and then
  • 00:07:11 we reload our app we can wait forever we
  • 00:07:14 won't see anything here and if we
  • 00:07:15 inspect our app root we see that the dev
  • 00:07:18 indeed is empty so nothing gets rendered
  • 00:07:20 here and the reason for this is that
  • 00:07:22 this is rendered as HTML code but it's
  • 00:07:25 not recognized as an HTML element app
  • 00:07:28 alert is not a built in element it's our
  • 00:07:30 own component but that exact is what I
  • 00:07:32 meant
  • 00:07:33 angular will not consider this after it
  • 00:07:36 has loaded our app because the
  • 00:07:38 compilation of the templates and
  • 00:07:39 therefore the part where it understands
  • 00:07:42 your component selectors is already done
  • 00:07:44 by that point of time and this doesn't
  • 00:07:46 change if we remove this from set
  • 00:07:48 timeout and execute it right at the
  • 00:07:51 beginning of this component so here we
  • 00:07:53 don't see anything even so this is not
  • 00:07:56 the reason the reason indeed is that
  • 00:07:57 angular doesn't compile this code and
  • 00:08:00 angular elements fixes this issue or
  • 00:08:03 this problem you could say it allows us
  • 00:08:06 to basically take our angular component
  • 00:08:09 and put it into a totally encapsulated
  • 00:08:12 self bootstrapping
  • 00:08:14 HTML element which you can dump into
  • 00:08:17 your angular app in this way for example
  • 00:08:19 and which will still work now how do we
  • 00:08:23 create such a component we need to
  • 00:08:25 install angular elements and you can
  • 00:08:28 already see that I added an import up
  • 00:08:29 here create custom element this has been
  • 00:08:32 lurking around for a while and it seems
  • 00:08:34 to be what we need now make sure that
  • 00:08:36 you install the angular elements package
  • 00:08:39 with npm install' – – safe at angular
  • 00:08:42 elements just in case this isn't
  • 00:08:45 installed already now I'm recording this
  • 00:08:47 with a beta version but of course but
  • 00:08:49 the point of time you're watching is it
  • 00:08:50 probably was released as part of the
  • 00:08:53 normal angular framework so once this is
  • 00:08:55 installed you should also ensure that
  • 00:08:58 especially for the beta version might
  • 00:09:00 not be a problem in later versions that
  • 00:09:02 you got rxjs compact because this is
  • 00:09:04 required for this to run at least right
  • 00:09:06 now and very important that you add this
  • 00:09:09 line to your package JSON fall this is a
  • 00:09:12 polyfill which right now all is required
  • 00:09:14 for this to run this might also change
  • 00:09:16 in the future but right now you need to
  • 00:09:17 add this so add this line with this
  • 00:09:20 version
  • 00:09:20 and rerun npm install' thereafter to
  • 00:09:23 download it and add it to your project
  • 00:09:25 and with that polyfill installed you can
  • 00:09:28 go to the polyfills TS file and there
  • 00:09:31 you should add these two lines import at
  • 00:09:35 web components slash custom elements
  • 00:09:37 slash custom elements dot min and import
  • 00:09:40 add web components slash custom elements
  • 00:09:42 slash source slash native shim this
  • 00:09:45 might also change in the future but we
  • 00:09:47 read now Nietzsche's to enable custom
  • 00:09:50 elements to ensure that this works that
  • 00:09:52 the native element there's custom
  • 00:09:54 elements package or the angular elements
  • 00:09:56 package sure spits out that this element
  • 00:09:58 works therefore this is needed so with
  • 00:10:02 that all added with the polyfills added
  • 00:10:04 on with the packages added we can now
  • 00:10:06 try creating a custom element and for
  • 00:10:09 this and a constructor of app component
  • 00:10:11 you want to do this in a place that runs
  • 00:10:12 early in your project I'll create a new
  • 00:10:15 element and I'll name it
  • 00:10:17 alert element the name is up to you I'll
  • 00:10:20 stored net constant which is named like
  • 00:10:22 this and I will use create custom
  • 00:10:24 element and now I need to import my
  • 00:10:27 custom element I want to do this on the
  • 00:10:29 alert element so you should make sure
  • 00:10:31 that you add an import to that so import
  • 00:10:34 alert component from and now it's alert
  • 00:10:41 component and there of course it should
  • 00:10:43 also be alert component element is the
  • 00:10:46 name of the constant but we pass in the
  • 00:10:48 component to create custom element now
  • 00:10:51 create custom element also needs a
  • 00:10:52 second argument this argument is used to
  • 00:10:55 configure this element and there we need
  • 00:10:57 to pass the injector we're using now
  • 00:11:00 angular uses dependency injection as you
  • 00:11:02 know and the injector is basically the
  • 00:11:04 tool which tests this injection and we
  • 00:11:06 provided to this custom element so that
  • 00:11:08 the element behind the scenes is able to
  • 00:11:10 connect itself to our app so to say
  • 00:11:13 therefore we simply inject the injector
  • 00:11:16 so import injector from at angular cord
  • 00:11:19 and with that injected in that object
  • 00:11:22 you're passing to create custom element
  • 00:11:24 you add the injector key and as a value
  • 00:11:27 the injector you're injecting that's a
  • 00:11:30 lot of injection going on I guess so
  • 00:11:32 with that we created a
  • 00:11:34 custom element and this indeed already
  • 00:11:36 is a native web component now we can use
  • 00:11:39 the custom elements API and important
  • 00:11:42 this is not an angular feature this is a
  • 00:11:45 feature provided by JavaScript and
  • 00:11:47 called the finder this allows us to
  • 00:11:50 register a custom web component and
  • 00:11:52 again alert element is just such a
  • 00:11:55 component it's the same as we could have
  • 00:11:56 built on our own so therefore here we
  • 00:11:59 first of all define the tag by which you
  • 00:12:02 want to select it and this doesn't have
  • 00:12:04 to be the same one as down here so we
  • 00:12:06 could also use my dash alert for example
  • 00:12:08 and then you pass in the element so not
  • 00:12:12 the component but alert elements are a
  • 00:12:14 custom element now with this we can use
  • 00:12:17 that so down there I use my alert
  • 00:12:19 instead of Apple Earth because I changed
  • 00:12:21 tag and now if we save this
  • 00:12:26 it compiles and if we go to our
  • 00:12:28 application nothing happens but if we
  • 00:12:33 inspect the console we actually got an
  • 00:12:35 error that we well that doesn't find a
  • 00:12:38 component Factory
  • 00:12:40 now as I said angular elements are only
  • 00:12:42 available in angular apps right now so
  • 00:12:45 what we have to do at this point of time
  • 00:12:47 is we have to add the entry components
  • 00:12:50 array to our app module entry components
  • 00:12:52 essentially is an array of components
  • 00:12:54 which you don't use with it's selector
  • 00:12:57 or wire routing but where you want to
  • 00:13:00 tell angular that you're eventually
  • 00:13:01 going to use it and this is exactly what
  • 00:13:04 will happen for the alert component we
  • 00:13:06 declare it that's important so today
  • 00:13:08 angular can find it but we also need to
  • 00:13:10 tell angular hey you won't see me use a
  • 00:13:12 selector for this you won't see me
  • 00:13:15 loaded with routing but eventually I
  • 00:13:17 will need it so please be prepared to
  • 00:13:20 load it when I need it and that is why
  • 00:13:23 we also have to load the angular
  • 00:13:24 component X using the alert component
  • 00:13:27 not our custom element but the angular
  • 00:13:29 component here into our entry components
  • 00:13:32 array and if we do that and we save the
  • 00:13:35 app will reload and we get at least a
  • 00:13:38 warning not an error sanitizing HTML
  • 00:13:41 stripped some content now the custom
  • 00:13:45 element is in the end a bunch of
  • 00:13:46 JavaScript code and this is sanitized so
  • 00:13:49 this can't be rendered with inner HTML
  • 00:13:51 that's a security mechanism to avoid
  • 00:13:55 cross-site scripting attacks we want
  • 00:13:58 this mechanism but in this case we know
  • 00:14:00 our content is safe and therefore we
  • 00:14:03 want to be able to output it we can do
  • 00:14:05 this with the help of the Dom sanitizer
  • 00:14:09 you can also uncheck this it's the Dom
  • 00:14:11 sanitizer object or class which you need
  • 00:14:15 to import from at angular platform
  • 00:14:18 browser and with it injected you can
  • 00:14:21 wrap this custom mm HTML code which
  • 00:14:24 again behind the scenes will use a lot
  • 00:14:26 of JavaScript you can wrap this with Dom
  • 00:14:29 sanitizer bypass security trust HTML so
  • 00:14:34 that this HTML code and whatever is
  • 00:14:38 connected to it is
  • 00:14:39 trusted so now with that if we reload
  • 00:14:43 this we do see our alert after a second
  • 00:14:45 but this time it's loaded as custom
  • 00:14:48 element if we inspect it we see our
  • 00:14:51 template here and we see the styles we
  • 00:14:54 applied to it but this now actually is
  • 00:14:57 loaded as a native web component still
  • 00:15:01 only usable in angular projects this
  • 00:15:03 will probably change in the future
  • 00:15:05 though but already useful for dynamic
  • 00:15:07 content like this since we sanitize it
  • 00:15:09 you should of course make sure that you
  • 00:15:11 know that this content is safe but with
  • 00:15:13 that you've got a really great tool to
  • 00:15:15 load content into your app and control
  • 00:15:19 it as an angular component and do all
  • 00:15:21 the fun stuff you can do with components
  • 00:15:23 whilst getting it from another source
  • 00:15:26 which is not hard-coded into your
  • 00:15:28 angular project code when you're
  • 00:15:30 compiling it