Trust, but Verify — Coerce Your Component Inputs

Tomasz Kula
Netanel Basal
Published in
3 min readJul 2, 2018

--

In this article, I’d like to talk about the @angular/cdk/coercion package. It exposes a few functions, which make designing components with flexible inputs a breeze.

We’ll have a look at the following:

  • coerceBooleanProperty
  • coerceNumberProperty
  • coerceArray
  • coerceCssPixelValue

CoerceBooleanProperty

Coerces a data-bound value (typically a string) to a boolean.

Say you want to design a carousel component. It should have an autoplay input that disables or enables the auto-play behavior.

You can now use it like this:

This indeed works, but it would be nice if the component consumers could also use it like this:

Unfortunately, at this point autoplay input equals to ‘’ which evaluates to false. This breaks the auto-play logic.

We can amend this with the use of coerceBooleanProperty :

Now the carousel auto-play will work as expected.

To have a better understanding of how the coerceBooleanProperty works, we can have a look at its specs:

it('should coerce the boolean true to true') 
it('should coerce the string "true" to true);
it('should coerce an arbitrary string to true');
it('should coerce an object to true');
it('should coerce an array to true');
it('should coerce the empty string to true')
it('should coerce zero to true)
it('should coerce undefined to false')
it('should coerce null to false');
it('should coerce the string "false" to false');
it('should coerce the boolean false to false');

CoerceNumberProperty

Coerces a data-bound value (typically a string) to a number.

Say you want to create a counter component.

Inside the component, you expose value and tick input properties.

Users might also want to use the component like this:

To make this work, we must implement setters for counter and tick properties:

coerceNumberProperty takes a second argument — the default coercion value. We use it in a counter setter to default the value to 0.

So in the case of <counter value="not a valid number"> the value input will be coerced to 0.

Quick look at the specs:

it(“should coerce undefined to 0 or default”);
it(“should coerce null to 0 or default”);
it(“should coerce true to 0 or default”);
it(“should coerce false to 0 or default”);
it(“should coerce the empty string to 0 or default”);
it(“should coerce an object to 0 or default”);
it(“should coerce an array to 0 or default”);
it(“should coerce an arbitrary string to 0 or default”);
it(“should coerce an arbitrary string prefixed with a number to 0 or default”);
it(‘should coerce the string “1” to 1’);
it(‘should coerce the string “123.456” to 123.456’);
it(‘should coerce the string “-123.456” to -123.456’);
it(“should coerce the number 1 to 1”);
it(“should coerce the number 123.456 to 123.456”);
it(“should coerce the number -123.456 to -123.456”);

CoerceArray

Wraps the provided value in an array, unless the provided value is an array.

CoerceArray can be used any time you‘d rather deal with an array and not a single value.

The component can be used like this:

Quick look at the specs:

it('should not wrap an array in an array');it('should wrap a string in an array');
it('should wrap a number in an array');
it('should wrap an object in an array');
it('should wrap a null vall in an array');
it('should wrap an undefined value in an array');

CoerceCssPixelValue

Coerces a value to a CSS pixel value.

Let’s create a bordered-box component which exposes the borderWidth input.

If the user doesn’t specify any unit, the value will default to pixels. Otherwise , we honor the provided unit (px, em, rem). The component can be used like this:

Quick look at the specs:

it(‘should add pixel units to a number value’)it(‘should ignore string values’)
it(‘should return an empty string for null’)
it(‘should return an empty string for undefined)

I’ve given you some of the examples of how to use coercion, but a lovely way to explore other use cases would be to search the @angular/material repository and find how the Angular Material team is using it.

The searches are listed by popularity, in descending order:

I’d also encourage you to read the source code for the coercion functions to understand how they work under the hood. Each function is only a few lines long, and they all have unit tests.

You can find all the components created in this article in the links below.

If you like the content, please clap 👏👏👏

To read more about Angular, follow me on Medium or Twitter.

--

--