Update: Iβve published an up-to-date article about Angular Elements. Check it out to learn about the latest API of Angular Elements:
π Angular Elements
— Nitay Neeman (@nitayneeman) April 7, 2018
I just published "A Practical Guide to Angular Elements" ππhttps://t.co/v6PKPb8qza#Angular #AngularElements #CustomElements #WebComponents #StackBlitz #JavaScript #js #WebDev #WebDevelopment #FrontEnd
Keep reading this article in order to get a sense of the concept.
Preface
Two and a half months have passed since Angular Elements project was revealed at the AngularConnect conference and shocked the Angular community:
Here's the slides from my Angular Elements talk @ #AngularConnect - https://t.co/4kuySZ9zMs
— robwormald (@robwormald) November 8, 2017
Along with a lot of excitement and expectation, it’s really important to remember that:
As of today, Angular Elements is just an experimental project of the Angular Labs.
Don’t get me wrong - this project is brilliant, without a doubt. But, you should know that itβs not ready for production purposes and either for development.
In case you’re not familiar with the Angular Labs term - it’s an idea that was announced during the AngularMix conference, in order to balance the community with new explorations - before these are released officially. In other words, it’s the place where the really cool things are started.
This article will examine what are the benefits of Angular Elements, through creating an experimental custom element and rendering it inside a non-Angular project, such as React.
What are Angular Elements?
Imagine that you’ve developed an awesome Angular component. However, in real life, not all the web applications are Angular-based or even single-page. You wish to use your amazing component as part of any web application in a non “hacky” way. Soon, there will be a neat way and it’ll be called - Angular Elements.
Angular Elements are ordinary Angular components, which are packaged as Custom Elements. In fact, Angular takes charge of initializing a custom element and bridging the attributes, events and lifecycle hooks between the component to that custom element.
“Angular Component on the inside, standards on the outside.” (Rob Wormald)
This approach let us develop reusable components in the way thatβs familiar to us, and yet, embedding these in every kind of website (vanilla JavaScript, React, Vue, WordPress, etc. - it really doesn’t matter).
Well, are you ready to build a custom element? π
Building a Custom Element
Let’s create a component to show the world how much we love the open source community:
Notice that’s an ordinary component, which displays a “Made With Love” message and receives a few parameters: the developer name, his website, a valid color format (RGB, Hex, etc.) and a size for the heart. The name
attribute is mandatory, so we log an error in case it’s undefined
or empty. We bind these attributes inside the appropriate template and display a non-clickable developer name when the URL isn’t provided.
The styles file is pretty straightforward, thus we won’t dive into it.
The next step is attaching the source code of @angular/element package inside our project, in order to import the registerAsCustomElements
function and the other necessary files. In practice, we should avoid that way of importation. However, these files aren’t available at this time on master - so when these are merged into master, we’ll install and import them like a regular Angular package. This package is targeted to be published as part of Angular 6. Update: It’s already available on master and you should install it like a regular package. Read my new article here.
Now, we register our component with the AppModule
:
In the above example, we create an array of custom elements. Also, we register its items with the declarations
and entryComponents
arrays. In case you didn’t know, “Entry Components” is an array of components which aren’t embedded in a particular template, but still created somehow imperatively.
As opposed to other AppModule
files - we don’t register a bootstrap component with this module, because we don’t have (and need) one like that. This is why ngDoBootstrap
is implemented as an empty stub as well.
Great, we’re making progress. So far, we created a component and registered it with a module - but, we haven’t done yet any distinctive thing with Angular Elements. Let’s get the hang of it!
As you know, there’s a main.ts
file for each Angular application. This is used as the main entry point which bootstraps the application. As mentioned above, we don’t have a bootstrap component. However, our custom element should have a self-bootstrapping capability. So, in order to achieve that, let’s use the registerAsCustomElements
function:
As you can see, we pass the customElements
to that function. After the bootstrapping process finishes, it takes each component in the provided array and wraps it with the Custom Element Web API. Currently, the browsers don’t support custom elements perfectly and thus we load several polyfills.
Take a look at the final result:
Live Previews
Well, it’s about time to give our custom element a try. You should know that my blog isn’t an Angular-based (based on Hugo actually) so it’s a perfect match to render the element here:
In case you traverse the DOM of this page, you’ll notice the following usage alongside its scripts file:
As I promised you, here’s an example for a React project that renders our custom element:
Conclusion
Angular Elements will provide a way to share our components everywhere on top of custom elements (web components). We covered this new way with a brief introduction and building an embeddable Angular element.
Here are some references you’d probably like to check out:
- Angular Elements β Rob Wormald (AngularConnect 2017)
- Angular Elements β Pascal Precht (NG-BE 2017)
- Angular Elements source code
- Custom Elements Web API
- made-with-love Repository
- An experimental starter project for Angular Elements
- A brief update for Angular Elements plan