The TRUE difference between [] and {{}} bindings in Angular
Tags: angular, javascript, webdev
Published: 2021-04-12 16:47:53

Joe Eames | ng-conf | Sep 2020

One of the parts of Angular that most developers think they understand, but many don’t, is the true nature of `[]` and `{{}}` bindings.

A fundamental lack of understanding of these bindings can become a major issue when working with templates and trying to get them to do exactly what you want. It can also be the cause of spending an unnecessary amount of hours trying to figure out a bug.

So I’m going to run down exactly what these two bindings do, and what it is that many developers misunderstand about them.

You’re probably familiar with the typical usage of `{{}}` bindings:

```
<h1>{{title}}</h1>
```

And you’re probably familiar with the typical usage of `[]` or property bindings:

```
<img [src]="imgsrc">
```

But do you truly understand what each binding is doing? And why we use them in this situation? Many if not most developers simply know to use `{{}}` when putting text in an element, and `[]` for binding to properties.

But have you ever wondered with reactive forms why the `formControlName` property doesn’t use the `[]` binding?

```
<input formControlName="title" >
```

A foundational understanding of what is going on will help you understand when and why you need to use `[]` or `{{}}` or nothing (like with the formControlName property)

So let’s start by discussing the difference between the following two lines:

```
<img [src]="imgsrc">
<img src="{{imgsrc}}">
```

Both will accomplish the same thing. They both set the src attribute of the image tag.

It’s also important to understand that both of them are running an evaluation on the imgsrc property which must be in your component. In both, they are using Angular’s expression syntax. So you can do things like the following:

```
<img [src]="'/images/' + name + '.png'">
<img src="{{'/images/' + name + '.png'}}">
```

This is an expression that does string appending to ultimately arrive at the URL for the image, appending together a root directory, a name, and an extension.

Note that you can’t mix `[]` and `{{}}` together on the same attribute. Angular will complain.

So what’s the ultimate difference between the two?

It comes down to how they function. `{{}}` is basically a form of string interpolation. You should think of it as simply replacing the HTML string with the results of the binding, and then the HTML gets evaluated.

Property binding, `[]`, on the other hand, works differently. You should think of this as manipulating the DOM **after** the HTML has been processed by the browser.

So the [src] binding actually manipulates the src property of the image object, and NOT the src attribute of the img tag.

The reason this matters is that the property binding - since it’s not string interpolation - can preserve data types.

Consider the following part of a form:

```
<input formControlName="isVisible" name="isVisible" type="radio" 
value="true"> True
<input formControlName="isVisible" name="isVisible" type="radio" 
value="false"> False
```

This HTML doesn’t bind the isVisible part of the form to the boolean values true and false. If you thought it does you have fallen victim to the subtle issues with binding. This code binds the isVisible property to either the string “true” or the string “false”. And any non-empty string is truthy. So if you then used that in a ngIf expression

```
<h1 *ngIf="myForm.value.isVisible">I'm only visible if the radio 
button is set to True</h1>
```

This won’t work. The ngIf will always evaluate to true.

BUT if you bind to the value PROPERTY

```
<input formControlName="isVisible" name="isVisible" type="radio" 
[value]="true"> True
<input formControlName="isVisible" name="isVisible" type="radio" 
[value]="false"> False
```

Then you are now binding the isVisible property to a boolean true or false.

But you can’t do this with the `{{}}` binding

```
<input formControlName="isVisible" name="isVisible" type="radio" 
value="{{true}}"> True
<input formControlName="isVisible" name="isVisible" type="radio" 
value="{{false}}"> False
```

This produces the same result as the first example. It’s ultimately just the string “true” and the string “false”.
That is the fundamental thing that most Angular developers don’t understand. Property bindings are actually manipulating the DOM and they get to preserve data types. Curly brace binding is string interpolation of the HTML and always results in strings.

Once you understand this, you can avoid a lot of potential bugs.

Happy Coding.

## **ng-conf: The Musical is coming**
ng-conf: The Musical is a two-day conference from the ng-conf folks coming on April 22nd & 23rd, 2021. Check it out at [ng-conf.org](https://www.2021.ng-conf.org/)