Boolean HTML attributes in Angular

I’ve been learning Angular and using it to make a website at work. I made a component that could work in two different modes, so I had a boolean (true/false) variable in the component to represent which mode the component was in. Some aspects of the DOM then are changed according to the variable, such as some attributes that are themselves boolean.

My adventures in figuring out how to do this inspired me to write this blogpost summarising what I found.

Boolean HTML attributes

To make an input (enabled by default), it’s <input />

To make a disabled input, it’s <input disabled />

This is the same as <input disabled="true" />, <input disabled="disabled" />.

This is also the same as <input disabled="" /> and <input disabled="false" /> because it is the presence of the disabled attribute that makes it disabled, not its value!

(The HTML spec says "true" and "false" are invalid values for boolean attributes, but browser behaviour is as I’ve described it.)

There are a few other boolean attributes like this, such as required and hidden. However, Aria attributes behave differently: <input aria-hidden="false" /> means not hidden to assistive tech.

(For more detail about Aria/non-Aria boolean attributes, Hidde de Vries has a good article.)

Binding on boolean attributes in Angular

For Angular, assuming myVariable is a boolean variable that we are binding to:

The latter behaviour is what I want, but the || null looks awkward.

But wait, that’s not quite valid HTML, even if it works in browsers. So I changed it to <input [attr.disabled]="myVariable ? 'disabled' : null" />

This is more verbose, but we get valid HTML of <input disabled="disabled" /> or <input />

Comparison with the Angular docs

The Angular documentation confirms that <input [attr.disabled]="myVariable ? 'disabled' : null" /> is a valid way of doing it. So that’s how I did it.

Is there a nicer Angular syntax?

A colleague wrote the equivalent of <input [attr.disabled]="myVariable ? '' : null" />, with the empty string. This is valid, and shorter. It took me by surprise to see '' used as a truthy value, because in JavaScript it’s falsy, but this is DOM attributes and it’s different.

The docs also suggest <input [disabled]="myVariable ? true : false"> — but I find this doesn’t work for my case, where the variable depends on URL parameters. When the component mounts, the variable is false (the default for a boolean) and then it is set to true (or false) when the URL gets read. Angular sees the initial false value and removes the disabled attribute to match that. But Angular doesn’t update the attribute when the variable becomes true, so the field is never disabled.

Throughout this blogpost I’ve been saying “attribute”. The Angular docs make a clear distinction between attributes (the initial values set in HTML) and properties (the live values in the DOM). This is funny because it’s the [attr.disabled] syntax that works for me in setting the live value.

Caveats