Angular Icon Get 67% off the Angular Master Bundle!

See the bundle then add to cart and your discount is applied.

0 days
00 hours
00 mins
00 secs
Angular

Angular Template Reference Variables In-Depth

In this post you’ll learn how to use Template Reference Variables, often known as “Template Refs”, in Angular.

In Angular, components have a template property, that holds elements and other components. A template reference variable is a feature that allows us to gain access to a part of our template.

This could be an element, component, or could be a directive. Template reference variables are cleverly implemented and can be used in various ways.

The first might be to simply export a reference to an element. Here we can attach a # to an <input> and provide a variable name (hence the template reference ‘variable’):

<input type="text" #coffee>

You can think of this syntax as an “export”. We are exporting a reference to the element.

That means that we can now access properties on that reference variable as if it was returned to us through plain JavaScript (think what you’d get back using document.querySelector('input') and that’s what we have here):

<input type="text" #coffee>

<p>{{ coffee.value }}</p>

This would log out an empty string for coffee.value as we have no value. Our coffee variable is directly giving us an HTMLInputElement.

For us to see the value as we type, we would need to introduce the ngModel Directive:

<input type="text" ngModel #coffee>

<p>{{ coffee.value }}</p>

Give it a try and type something into the <input>:

So here’s the next great feature of template refs.

Let’s export a reference to our ngModel and change the context of what #coffee returns us.

By specifying #coffee we are implicitly letting Angular decide what to export, because we are not specifying anything other than binding to the element.

We’re binding ngModel, which is now ‘part of’ our <input>. Let’s export it:

<input type="text" ngModel #coffee="ngModel">

<p>Value: {{ coffee.value }}</p>
<p>Pristine: {{ coffee.pristine }}</p>
<p>Touched: {{ coffee.touched }}</p>

By passing #coffee="ngModel" we are explicitly binding a reference to our tracked ngModel directive.

No longer do we have an HTMLInputElement. We have a reference to NgControl.

You can check the source code for NgControl here, which extends the NgControl and AbstractControlDirective classes.

Why are we looking at this? Because it shows you every property available to you, which is exactly why we’ve referenced not only value but pristine and touched as well.

Try them out below, our template reference variable is mirroring the ngModel:

We can further this and access a template ref inside a component, so we can access properties and methods from inside the class and not just the template.

This is achieved through using perhaps TemplateRef or ElementRef alongside a @ViewChild decorator. Read the above article on how to do it and more deep working, but essentially it looks like this:

@Component({...})
export class AppComponent {
  @ViewChild('username') input: ElementRef<HTMLInputElement>;
}

That’s a nice introduction to template refs, and I hope it gives you some deeper understanding as to how to use them, when and where. Not only this, but what to expect back when you declare a template ref and how to also export references to things like directives.

If you are serious about your Angular skills, your next step is to take a look at my Angular courses where you’ll learn Angular, TypeScript, RxJS and state management principles from beginning to expert level.

Happy reffing!

Related blogs 🚀

Free eBooks:

JavaScript Array Methods eBook Cover

Ready to go beyond ForEach? Get confident with advanced methods - Reduce, Find, Filter, Every, Some and Map.

NestJS Build a RESTful CRUD API eBook Cover

Build your first NestJS app. With the CLI you'll learn the basics of real-world NestJS development.