Angular Basics: What are components?

This is the first post in a mini series covering Angular basics. Today I'm going to talk about components, what they are and how they work. We are going to work through creating a basic component to display a list of recipies.

What is a Angular component?

The Angular documentation describes a component as follows.

"a component controls a patch of screen called a view"

That gives us the high level role of a component but how does it actually work? Well, I'm glad you asked.

An Angular component is made up of 3 parts:

  • Template
  • Class
  • Metadata

Template

The template of a component is a HTML fragment which defines what is rendered on the page.

This can be something as simple as a h1 tag or it could be something more complex such as a form with custom validation. It can even be rendering more components. Templates can use standard HTML but the power of the template is in being able to use directives and bindings.

The template can be defined in the component file as part of the metadata. But it's usually best practice to define the template in its own file. Below is an example of a template file.

<h1>Recipies</h1>

<ul>
  <li *ngFor="let recipe of recipies">{{recipe.name}}</li>
</ul>

As you can see there are standard HTML tags but they are mixed with some markup that probably looks a bit odd. *ngFor is an example of a directive and {{ item.decription }} is an example of a binding. This template syntax will be processed by Angular when rendering the component and will result in markup that looks more like this.

<h1>Recipies</h1>

<ul>
  <li>Lasagne</li>
  <li>Roast Beef</li>
  <li>Chicken Pie</li>
  <li>Bean Burger</li>
</ul>

Class

The class is the engine of the component and contains the code required to support the template.

Classes are written using TypeScript. It is possible to use JavaScript although this is not recommmended. The class exposes properties and methods, much the same as a C# class, which can be accessed by the template. We have already seen one side of this in the template example above, where the *ngFor accessed the recipies property. Lets take a look what this looks like from the class side.

export class RecipeList {

    recipies: Recipe = [];
    
    constructor() {
        let recipe1 = new Recipe("Chicken Pie");
        let recipe2 = new Recipe("Roast Beef");
        let recipe3 = new Recipe("Pasta Bake");

        this.recipies.push(recipe1, recipe2, recipe3);
    }

}

In the RecipeList class above I've just exposed a property recipies which contains an array of Recipe objects. The template can then bind to the recipies property and, as per the example in the templates section, iterate over the array.

Metadata

Metadata is defined using a decorator. A decorator is just a function, which takes an object, that adds metadata to a class or its members.

There are 4 main types of decorator available in Angular:

  • Class decorators
  • Method decorators
  • Property decorators
  • Parameter decorators

For now I am just going to talk about the @Component class decorator. By just adding the @Component decorator above a class Angular will know that it is a component.

Lets turn the RecipeList class above into a component as an example.

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

@Component({
    selector: 'recipe-list',
    templateUrl: './recipe-list.html'    
})
export class RecipeList {

    recipies: Recipe = [];
    
    constructor() {
        let recipe1 = new Recipe("Chicken Pie");
        let recipe2 = new Recipe("Roast Beef");
        let recipe3 = new Recipe("Pasta Bake");

        this.recipies.push(recipe1, recipe2, recipe3);
    }

}

First, I've imported the Component decorator from the @angular/core package. Then I've added the @Component decorator and passed it an object which contains the location of the template to use (templateUrl) and the HTML selector (selector) for this component. There are many pieces of information that can be included in the object passed to the decorator.

  • styles
  • providers
  • inputs
  • outputs
  • changeDetection
  • host
  • etc....

Please check out the official docs for the complete list.

The Completed Component

We have now covered the three building blocks of components so lets put them all together and see what it looks like.

recipe-list.html

<h1>Recipies</h1>

<ul>
  <li *ngFor="let recipe of recipies">{{recipe.name}}</li>
</ul>

recipe-list.component.ts

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

@Component({
    selector: 'recipe-list',
    templateUrl: './recipe-list.html'    
})
export class RecipeList {

    recipies: Recipe = [];
    
    constructor() {
        let recipe1 = new Recipe("Chicken Pie");
        let recipe2 = new Recipe("Roast Beef");
        let recipe3 = new Recipe("Pasta Bake");

        this.recipies.push(recipe1, recipe2, recipe3);
    }

}

Wrapping Up

Components are made up of three parts template, class and metadata. We have seen how we can use a mixture of HTML and template syntax to create rich views for a component. We learned how powerful decorators are in Angular and how to transform a simple TypeScript class into an Angular conponent using the component decorator.