Our content is free thanks to ag-Grid

ag-Grid is the industry leading JavaScript datagrid

ag-grid.com

Simplifying Web Components usage with Angular Elements

Post Editor

In this article we'll explore what are web components and why we care, their use cases and how/where Angular Elements comes into play.

4 min read
post

Simplifying Web Components usage with Angular Elements

In this article we'll explore what are web components and why we care, their use cases and how/where Angular Elements comes into play.

post
post
4 min read
4 min read

Web Components, Micro-Frontends and Domain Driven Development are just a few buzzwords that seem to be getting thrown around in the space of Web Development at the moment.

This is Part 1 of a series of articles that will outline the what/why/how. We'll explore what are Web Components and why we care, their use cases and how/where Angular Elements comes into play.

In part 2 we look at:

  • Building and Bundling Web Components in Angular.
  • Other approaches available to us using IVY.
  • Some limitations and possible solutions.
  • Some key tools.

Although many parts will be directed towards Angular, the great thing about Web Components is their framework agnostic nature.  The concepts herein described therefore, can/are applicable to other frameworks and even VanillaJS.

What are Web Components

“Web Components is a suite of different technologies allowing you to create reusable custom elements — with their functionality encapsulated away from the rest of your code — and utilize them in your web apps.” MDN web docs

In other words Web Components gives the developer the ability to create custom elements that the browser will render and treat just like a builtin element, e.g <button>.

Why do we care?

On the surface, it might seem like this is not a big deal.  Despite implementation differences, web frameworks generally have the idea of reusable code (components) that will render to the DOM.

Let’s look at a Date Picker.

Googling “Javascript Date Picker” you will see multiple results. Some will be written in vanilla Javascript, others using jQuery and then a plethora for the different frameworks.  The implementations will range vastly but most share a huge amount of the same functionality.

If you are a solo programmer or small company that only codes in one framework, this really is not a problem. You pick one and run with it.  For larger companies where they may use multiple frameworks, enforcing design and functionality consistency across the software estate can be challenging.  

Having one Web Component that can be reused across all frameworks and give consistent functionality can save a lot of work and headaches.

Other use cases

Creating simple Web Components, like a Date Picker, is great when you want to build a reusable component library, but can we do more? A trend that is going around at the moment is Micro-Frontends.

The idea behind Micro-Frontends is you arrange your frontend application as a collection of loosely coupled smaller apps. These smaller apps aim to mirror the microservices in the backend.  This creates encapsulated domain level vertical slices e.g. Login, Customer Profile, Products, Order Process etc.

This vertical slicing gives domain/app autonomy and in turn leads to: incremental upgrades, independent deployments and a decoupled code base.  A great benefit when you start to think about Enterprise level applications/codebases.  Web Components are huge enablers of this architecture design approach.

If we think about a single Web Component containing multiple components that encapsulates a single domain we start to see a clean path for Micro-Frontends.

How to use Web Components?

The great thing about Web Components is that they are treated by the browser as normal html elements.  They have a constructor and lifecycle callbacks. When the html is parsed, the browser instantiates a new node for our Custom Element.

Using the CustomElementRegistry object, we can add new Custom Elements to the page.

class HelloWorldClass extends HTMLElement {

    constructor() {
        // Always call super first in constructor
        super();
    }
    …
    …
}

customElements.define('hello-world', HelloWorldClass);

With the last line of code we are registering the HelloWorldClass, which will be used when the tag “hello-world” is parsed.

Simple right? Well yes it is if all you want to create is a helloworld type Web Component.  What about all those good things that we are used to, like custom events, attributes, properties and the reflection of properties to attributes? Things become a bit more involved:

class HelloWorldClass extends HTMLElement {
    static get observedAttributes() {
        return ['title’];
    }
    
    get disabled() {
        return this.hasAttribute('disabled');
    }
    
    set disabled(val) {
        if (val) {
            this.setAttribute('disabled', '');
        } else {
            this.removeAttribute('disabled');
        }
    }
    
    constructor() {
        // Always call super first in constructor
        super();
        // Setup a click listener on <hello-world> itself.
        this.addEventListener('click', e => {
            ...
        });
    }
    
    // Only called for the disabled and open attributes due to observedAttributes
    attributeChangedCallback(name, oldValue, newValue) {
        switch (name) {
            case 'title':
                this.component.title = newValue;
                break;
        }
    }
    
    get title(){
        return this.hasAttribute(title);
    }
    
    set title(value) {
        if (val) {
            this.setAttribute(‘title’, val);
        } else {
            this.removeAttribute(‘title’);
        }
    }
    
    …
}

As you can see things slowly get more complicated and this is only for one event and one attribute.

In the world of angular there is @angular/elements which is here to help. This package will take a component of your choice and wrap it in a Custom Element. It automatically creates all the bindings for you and scaffolds everything the component requires to manage the view and state.

The best part is you can do it in two lines:

import { createCustomElement } from '@angular/elements';

createCustomElement(component, config);

The Web Component spec has enabled developers to create reusable components that work natively with the browser.  This is great for creating a component library. It gives design and functionality consistency across your company’s app suite, but does not restrict your developers to any one framework.  Taking the Web Components to the next level, we can use it to help architect and implement Micro-Frontends.  The almost drag and drop functionality that we get means domain development teams can work autonomously. The concept of decoupling service and creating microservices has been a widely adopted backend architecture and now Web Components can help bring it to the frontend without having to consider less desirable web technologies like iFrames.

Discuss with community

Share

About the author

author_image
Chris Williams

OSS Contributor. Frontend Architect and Developer. Enthusiast about all things web development and Serverless!

author_image

About the author

Chris Williams

OSS Contributor. Frontend Architect and Developer. Enthusiast about all things web development and Serverless!

About the author

author_image
Chris Williams

OSS Contributor. Frontend Architect and Developer. Enthusiast about all things web development and Serverless!

NxAngularCli
NxAngularCli
NxAngularCli

Featured articles

RxJSpost
21 January 20214 min read
RxJS in Angular: Part III

In my previous two articles we have discussed how to change our components which solve problems in imperative ways to do that in functional, reactive, RxJS way, and we of course had a lot of fun doing that.

RxJSpost
21 January 20214 min read
RxJS in Angular: Part III

In my previous two articles we have discussed how to change our components which solve problems in imperative ways to do that in functional, reactive, RxJS way, and we of course had a lot of fun doing that.

Read more
RxJSpostRxJS in Angular: Part III

21 January 2021

4 min read

In my previous two articles we have discussed how to change our components which solve problems in imperative ways to do that in functional, reactive, RxJS way, and we of course had a lot of fun doing that.

Read more
Angularpost
20 January 20216 min read
Angular and SOLID principles

In software engineering, making things work the first time is always easy. But, what if you want to add new functionalities to an existing code? Making iterations on an existing basis can be difficult to do without introducing bugs. This is where SOLID principles come into play.

Angularpost
20 January 20216 min read
Angular and SOLID principles

In software engineering, making things work the first time is always easy. But, what if you want to add new functionalities to an existing code? Making iterations on an existing basis can be difficult to do without introducing bugs. This is where SOLID principles come into play.

Read more
AngularpostAngular and SOLID principles

20 January 2021

6 min read

In software engineering, making things work the first time is always easy. But, what if you want to add new functionalities to an existing code? Making iterations on an existing basis can be difficult to do without introducing bugs. This is where SOLID principles come into play.

Read more
Angularpost
14 January 20216 min read
Demystifying Taiga UI root component: portals pattern in Angular

Just before new year we announced our new Angular UI kit library Taiga UI. If you go through Getting started steps, you will see that you need to wrap your app with the tui-root component. Let's see what it does and explore what portals are and how and why we use them.