Cory Rylan

My name is , Google Developer Expert, Speaker, Software Developer. Building Design Systems and Web Components.

Follow @coryrylan
Angular

Angular Tips: Template Binding with Static Types

Cory Rylan

- 3 minutes

Updated

This article has been updated to the latest version Angular 17 and tested with Angular 16. The content is likely still applicable for all Angular 2 + versions.

In Angular, we have the availability to use TypeScript and editor tools that can statically analyze our components. Editors can provide autocompletion feedback and can detect typos in our templates. In this post, we will cover a couple of tricks that can help prevent pesky typos in our HTML templates and catch errors at build time rather than run time.

A frequent use case is toggling the visibility or CSS class of a DOM element. Usually, we toggle this information on some type or state. For example, in our app, we have different notification messages we want to display to the user such as an error or success message.

In our example, we will toggle the visibility and styles of the element based on the type. In our use case, we have a message component to display messages to users in various states. Our message states are the following: Success, Error, Warning, and Default.

Angular Message Component with Template Binding

Static Analysis

Our message component has two inputs. First, it takes the message type, example error vs. success. The second input is included via ng-content is the actual message we would like to display. Let's take a look at the message component below.

import { Component, Input, OnInit } from '@angular/core';

export enum MessageTypes {
  Default,
  Success,
  Error,
  Warning
}

@Component({
  selector: 'app-message',
  template: `
    <div
      class="message"
      [ngClass]="{
        'message--error': messageTypes.Error === type,
        'message--success': messageTypes.Success === type,
        'message--warning': messageTypes.Warning === type
      }"
    >
      <ng-content></ng-content>
    </div>
  `
})
export class MessageComponent implements OnInit {
  @Input() type = MessageTypes.Default;

  messageTypes = MessageTypes;
}

Our component has the one input for the type of message to display and then displays the content with the ng-content feature. Ng content takes whatever content we place in the component tags and inserts it into our template. We will see this in just a moment.

The important thing to notice in our component above is our enum we are using for the message types. We can bind the enum to our component property.

export enum MessageTypes {
  Default,
  Success,
  Error,
  Warning
}

What does this give us? We can now reference a property in our templates instead of magic strings.

<div
  class="message"
  [ngClass]="{
  'message--error': messageTypes.Error === type,
  'message--success': messageTypes.Success === type,
  'message--warning': messageTypes.Warning === type
}"
>
  <ng-content></ng-content>
</div>

Now if refactor our code there or no magic string duplicated across our code base, and we can rename and refactor as needed.

Editor Autocompletion

This technique also makes it easier to use our components and understand the API signatures. Below is my component that is using the app-message component.

import { Component } from '@angular/core';

import { MessageTypes } from './message.component';

@Component({
  selector: 'demo-app',
  template: `
    <app-message [type]="messageTypes.Error">
      Error: Hello World
    </app-message>
  `
})
export class AppComponent {
  messageTypes = MessageTypes;
  constructor() {}

  ngOnInit() {}
}

We can see we bind the message type enum to our demo component. Now in our templates we will get static typing, and our editor can provide autocompletion like below.

Taking advantage of TypeScript and Angular template syntax we can help lower the chances of production run time errors and catch them early in development. Check out the working demo below. To see the template static type checking in action copy the demo into an editor with TypeScript support like Visual Studio Code.

View Demo Code   
Twitter Facebook LinkedIn Email
 

No spam. Short occasional updates on Web Development articles, videos, and new courses in your inbox.

Related Posts

Angular

Creating Dynamic Tables in Angular

Learn how to easily create HTML tables in Angular from dynamic data sources.

Read Article
Web Components

Reusable Component Patterns - Default Slots

Learn about how to use default slots in Web Components for a more flexible API design.

Read Article
Web Components

Reusable Component Anti-Patterns - Semantic Obfuscation

Learn about UI Component API design and one of the common anti-patterns, Semantic Obfuscation.

Read Article