Angular 5 Quickstart. Part 3: Bindings

After part 1 and part 2 of our Angular 5 Quickstart journey we actually have a functional little app, which displays a list of JavaScript trivia. We’ll use this third part of the tutorial to make that even more flexible, and to add some extra bits of functionality.

Let’s start by reviewing our src/app.ts as it stands at the moment:

import { Component } from '@angular/core';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

@Component({
selector: 'trivia',
template: `
<h1>{{question}}</h1>{{answer}}

`
})

class TriviaComponent {
question: string;
answer: string;

constructor() {
this.question = "How many JavaScript scopes?";
this.answer = "Two. Global and Local.";
}
}

@Component({
selector: 'trivia-list',
template: `
<div trivia of trivias>
<h1>{{trivia.question}}</h1>
</div>
<div trivia of trivias>

{{trivia.answer}}

</div>
`
})
class TriviaListComponent {
trivias: Object[];

constructor() {
this.trivias = [
{
question: "How many JavaScript scopes?",
answer: "Two. Global and Local."
},
{
question: "What's a JavaScript closure?",
answer: "An inner function with access to the outer function's variables -scope chain."
},
];
}
}

@NgModule({
imports: [BrowserModule],
declarations: [TriviaComponent, TriviaListComponent],
bootstrap: [TriviaListComponent]
})
export class AppModule {
}

We’ll be improving our TriviaListComponent today, first by hiding the trivia answers and building some new functionality to display them at the click of a button.

Property binding

We begin by hiding the answers. Let’s update the template, hiding the answers with a hidden attribute as per below:

<div trivia of trivias>
<h1>{{trivia.question}}</h1>
</div>
<div trivia of trivias>

{{trivia.answer}}

</div>

What we did here was bind the value true to the DOM property hidden.

There is an almost one to one correspondence between Angular’s DOM properties and HTML attributes (HTML has a hidden attribute indeed, which works in similar ways in terms of hiding HTML elements). But HTML attributes are static, in the sense that HTML doesn’t automatically update the webpage, not unless the browser is refreshed. Changing the DOM however, and of course DOM properties as well, will instantly update the webpage. So we can manipulate these programatically, and this is what we’ll be doing shortly.

To begin with, we’d like each trivia to control its hidden/visible status somehow. We will start by adding a hidden property to the objects in our trivias array.

constructor() {
this.trivias = [
{
question: "How many JavaScript scopes?",
answer: "Two. Global and Local.",
hidden: true
},
{
question: "What's a JavaScript closure?",
answer: "An inner function with access to the outer function's variables -scope chain.",
hidden: true
},
];
}

Now, instead hardcoding the value of our hidden DOM property to true, we want to pass it the value of the looped trivia object’s hidden property, as per below:

{{trivia.answer}}

In the Live Preview panel, we should now only see the trivia questions, all answers being hidden for now.

Event binding

We want to show and hide the answers at the click of a button, so to begin with let’s add a button to the component template.

template: `
<div trivia of trivias>
<h1>{{trivia.question}}</h1>
</div>
<div trivia of trivias>

{{trivia.answer}}

<button type="button">Answer</button>
</div>`

Every time someone clicks the button, we want to hide show the answer, or hide it if it’s already visible.

template: `
<div trivia of trivias>
<h1>{{trivia.question}}</h1>
</div>
<div trivia of trivias>

{{trivia.answer}}

<button type="button">Answer</button>
</div>`

The above is pretty self explanatory, and is what we call an event binding. Every time a click event happens on the button, we tell Angular to in effect toggle the hidden property for our current trivia object. We expect some form of JavaScript code in between the double quotes there, and that could also be a function call. So we could enrich our TriviaListComponent class with a toggle method, as per below,

toggle(trivia) {
trivia.hidden = !trivia.hidden;
}

and update the component template accordingly:

<button type="button">Answer</button>

Our src/app.ts now looks as follows,

import { Component } from '@angular/core';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

@Component({
selector: 'trivia',
template: `
<h1>{{question}}</h1>{{answer}}

`
})

class TriviaComponent {
question: string;
answer: string;

constructor() {
this.question = "How many JavaScript scopes?";
this.answer = "Two. Global and Local.";
}
}

@Component({
selector: 'trivia-list',
template: `
<div trivia of trivias>
<h1>{{trivia.question}}</h1>
</div>
<div trivia of trivias>

{{trivia.answer}}

<button type="button">Tell me</button> `
})
class TriviaListComponent {
trivias: Object[];

</div>
constructor() {
this.trivias = [
{
question: "How many JavaScript scopes?",
answer: "Two. Global and Local.",
hidden: true
},
{
question: "What's a JavaScript closure?",
answer: "An inner function with access to the outer function's variables—scope chain.",
hidden: true
},
];
}

toggle(trivia) {
trivia.hidden = !trivia.hidden;
}
}

@NgModule({
imports: [BrowserModule],
declarations: [TriviaComponent, TriviaListComponent],
bootstrap: [TriviaListComponent]
})
export class AppModule {
}

and our app isn’t too bad either:

plunkr5.png

That’s it for today, we’ll continue improving this in further post. In the meantime, make sure you check parts 1 and 2 of this tutorial if you haven’t already, and as always, happy coding!