Angular Databinding Tutorial

In this Angular tutorial we learn how to communicate between the view and the model with databinding.

We learn one way databinding with string interpolation, property binding and event binding but we also look at how to combine them for two-way communication.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

What is Databinding

We can think of databinding as the communication between the View and the Logic.

There are three types of databinding in Angular.

  • One way databinding from the Javascript Logic to the HTML View.
    • Here we output data from the Logic in the View with String Interpolation or Property binding.
  • One way databinding from the View to the Logic.
    • Here we can react to events from the HTML, like a button click, with Event binding.
  • Two way binding between the logic and the view.
    • Here we combine the two one way bindings. We can react to events and output something at the same time.

Lesson project setup

For this lesson there is no initial setup other than having an app.

To keep things simple, we will be working directly from inside the main ‘app.component’ component and will create whatever else we need on a step-by-step basis.

String Interpolation

String interpolation is used to take dynamic data that’s in a .component.ts file (the Logic), and show it in a .component.html file (the View).

We saw this in the First App lesson where we used {{ title }} in the app.component.html file to show the title defined in the app.component.ts file.

As an example, let’s consider that we have an app with a member area and we want to display a greeting to the member when they enter.

The data can come from an external HTTP request like a database or a JSON file or something similar. To keep things simple for the example, we will just hardcode the value into the component class.

We can do this in the default ‘app’ component, so open the app.component.ts and app.component.html files.

They should look something like this.

Example: app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'my first app';
}
Example: app.component.html
<h1>{{ title }}</h1>
<hr>

We’re already using string interpolation but let’s do it ourselves.

1. In the AppComponent class, add a property called ‘username’ with any name as the value.

Example: app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'my first app';
  username = 'John Doe';
}

We will imagine, for the moment, that the value comes from a database of registered users.

If we want, we can use the explicit type feature in TypeScript by specifying the type after the property, separated with a colon.

Syntax:
property_name:type = value;
Example: app.component.ts
...
export class AppComponent {
  title:string = 'my first app';
  username:string = 'John Doe';
}
...

Although not necessary, it’s one of the features that makes TypeScript great and our code better, so it’s good to use it.

2. Now we can tell Angular that we want to pull the username from the logic, and display it in the HTML template.

We do this with double curly braces, specifying the property from the class between them.

Example: app.component.html
<h1>Hello {{ username }}, welcome to {{ title }}</h1>
<hr>

We’re not limited to just displaying a property, we can display any single line expression that resolves into a string.

This can be a method that returns a string, or a number that can easily be converted into a string. It cannot be a data structure like an if statement or for loop.

Let’s see an example.

Example: app.component.ts
...
export class AppComponent {
  title:string = 'my first app';
  username:string = 'John Doe';

  getUsername() {
    return this.username;
  }
}
...

The method above simply returns the value of the username property.

Example: app.component.html
<h1>Hello {{ getUsername() }}, welcome to {{ title }}</h1>
<hr>

We can also hard code the string by wrapping it in quotes. This is typically only for temporary placeholder content.

Example: app.component.html
<h1>{{ 'Greetings' }} {{ getUsername() }}, welcome to {{ title }}</h1>
<hr>

Property Binding

Property binding allows us to control the property of an HTML element from our Component.

If an element has a property, like onClick , then we can control it with Property Binding.

To do this we specify the property between square brackets, then assign a value to it.

Syntax:
<element [property]='value'></element>

As an example, let’s say we want to set the innerText property of our H1 element in the ‘app’ component with a nice greeting.

We can create a method in the Logic that concatenates the user’s name and a message to form the greeting.

Example: app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  user:string = 'John Doe';
  greeting:string = 'Welcome to my app';

  getGreeting() {
    return this.greeting + ', ' + this.user;
  }
}

We hardcode the username again for easy demonstration. Typically it would come from an external source.

Now we can simply specify the method as the property’s value. Whatever the method returns will then be the property’s value.

Example: app.component.html
<h1 [innerText]='getGreeting()'></h1>
<hr>

When we look at the page in the browser, we can see that the combined message from the method is displayed in the H1 tag.

Property Binding vs String Interpolation

String Interpolation and Property Binding seems similar, so when do we actually use which one?

It depends on what you’re doing.

  • If you want to output some text to your application, you should use String Interpolation.
    • For example, let’s say users can send messages to each other through our app. We could use String Interpolation to output the message on the screen.
  • If you want to edit the property of an element, you should use property binding.
    • For example, let’s say our app has a form that requires user input. We could disable the button by tapping into its disabled property, until the user has completed all the required fields.

One important thing to note is that we cannot mix property binding and string interpolation.

Example:
<h1 [innerText]='{{ getGreeting() }}'></h1>

The example above will raise an error because Angular does not allow us to use both together like that.

It looks like we’re modifying the HTML attribute, but we don’t. It’s a TypeScript expression. The syntax looks almost the same as the HTML syntax so it’s easy to become confused with what’s happening here.

Event Binding

Event Binding is how we react to events from the HTML template. This could be something like a user clicking on a button, or a mouse hovering over an element.

Event Binding syntax looks similar to Property Binding except we use parentheses instead of square brackets.

Syntax:
<element (property)='value'></element>

As an example, let’s say a user clicks the submit button on a registration form. Instead of redirecting to another page with a success message, we can show them the success message directly on the same page.

So we need two things.

  1. A property that will hold the message we want to display.
  2. A method that will show the message when the user clicks on the ‘Register’ button (when the event fires).
Example: app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  formMessage:string = '';

  onSubmitForm() {
    return this.formMessage = 'Thank you for registering. Please check your email for the verification link.';
  }
}

In our View, we add the formMessage property with String Interpolation to a paragraph. By default it won’t show anything because the property in the Logic is just an empty string.

Next, we put a ‘click’ event on the Register button that will call the method that changes the message.

The ‘click’ event is Angular’s event binding syntax for the Javascript ‘onClick’ event. With this syntax we simply remove ‘on’ from the word and make it all lowercase letters. For example, ‘onClick’ becomes ‘click’, or ‘onMouseEnter’ becomes ‘mouseenter’.

Example: app.component.html
<button (click)='onSubmitForm()'>Register</button>
<p>{{ formMessage }}</p>

When we click on the ‘Submit’ button in the browser, the message we defined in the onSubmitForm() method shows up.

Two-way Databinding

Two-way databinding allows us to combine Property and Event Binding to react to events and output data at the same time.

We also combine the syntax by specifying the square brackets with the parentheses inside them. Other than that, it looks the same as Event Binding syntax.

Syntax:
<element [(property)]='value'></element>

As an example, let’s say we want to allow our users to create an email address. As the user types their desired address, we want to show them what the full one will look like.

For this we will only need a single string property in the Logic, called ‘emailAddress’.

Example: app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  emailAddress:string = '';
}

In the View we need an input for the user to type in, and somewhere to display the full address.

Example: app.component.html
<input type="text" [(ngModel)]="emailAddress">
<p>{{ emailAddress }}@mail.com</p>

To react to the event of the user typing, we use a directive called ngModel that targets the emailAddress property on an input.

To output data at the same time as the event, we simply use String Interpolation and show the typed email address in a paragraph.

That’s pretty much all that’s needed in two-way databinding. However, this example will not compile right now.

Because we’re working with an input, we need to import and register the FormsModule into our app.module.ts file.

Example: app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
// Import FormsModule because we're working with input
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule    // Register FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now our application will compile and we can test it in the browser by typing something in the input field.

The letters we type are displayed below the input directly as we type them.

We react to the event of the user typing and output data at the same time.