Angular Kenya Meetup
Tags: angular
Published: 2022-06-30 10:18:52

---
title: Angular Kenya Meetup
published: true
date: 2022-06-29 14:57:42 UTC
tags: Angular
canonical_url: https://blog.ag-grid.com/angular-kenya-meetup/
cover_image: https://blog.ag-grid.com/content/images/2022/06/angular-kenya-stephen-blog--tiny.png
---


Stephen Cooper presented at the Angular Kenya Meetup on June 23 2022. Explaining lessons learned from building components that are used by other people when they have template type checking enabled.

This allows IDEs to warn about type errors as we are coding to get early pre-compile time warnings.

With strict mode enabled by default, we must acknowledge that there is nothing more tiresome than using a component that is poorly typed. As we develop our components we must consider the implications of our Input types for developers that have strict mode enabled.

Just defining the Input types isn't enough to avoid type failures.

If you want to support shorthand boolean attributes then a declaration can't just be boolean.

```
public disabled: boolean = false;

```

Explicit attribute binding will work:

```
<app-display [disabled]="true"></app-display>

```

But when someone uses a plain attribute, it doesn't work because the default is equivalent to an empty string.

```
<app-display disabled></app-display>

```

This would generate a visual warning in the IDE because the types don't match and a "Type 'string' is not assignable to type 'boolean'."

There are two approaches to handling this depending upon the Angular/Typescript version.

In Angular v9-14 we can use `ngAcceptInputType_` for Input Coercion, or we use Set and Get with different types for Typescript v4.3 and Angular v13+.

`ngAcceptInputType_` is a static property supported by the Angular compiler that enables you to widen the accepted types of an input property.

The input is defined the normal way, but we also add a static `ngAcceptInputType_` property to allow the compiler to accept multiple types.

```
@Input()
public disabled: boolean = false;
static ngAcceptInputType_disabled: boolean | '';

```

But we still have to convert the empty string to true, using `ngOnchanges`:

```
ngOnChanges (changes: SimpleChanges) {
   if (changes.disabled) {
       this. disabled = toBoolean(changes.disabled.currentValue);
   }
}

toBoolean (value: boolean | string) {
    this.disabled = (value === '') || value === true;
}

```

This can be done for other types as well, e.g. Dates:

```
@Input ()
public date: Date;
static ngAcceptInputType_date: Date | string;

ngOnChanges (changes: SimpleChanges) {
    if (changes.date) {
        this.date = toDate(changes.date.currentValue);
    }
}

```

However, will Inputs be set with the async pipe? Do you handle the initial null values?

e.g. if the user is setting the `disabled` value from an Observable stream

```
disabledStream$: Observable<boolean>;

```

And:

```
<app-display [disabled]="disabledStream$ | async"></app-display>

```

An Async pipe returns null when no values have been emitted yet.

We would amend the `ngAcceptInputType_` to handle null.

```
static ngAcceptInputType_disabled: boolean | '' | null;

```

With Typescript 4.3 we can now use Get and Set with different types.

```
_disabled: boolean = false;

@Input()
get disabled(): boolean{
   return this._disabled;
}

set disabled(value: boolean | string | null){
   this._disabled = toBoolean(value);
}

```

With no need any more for `ngAcceptInputType_`.

We can also handle compilation failures for 3rd party components in our code:

Non null assertions with "!":

```
<app-display [disabled]="(disabledStream$ | async)!"></app-display>

```

Disable type checking with "$any()":

```
<app-display [disabled]="$any(disabledStream$ | async)"></app-display>

```

Provide a default value "|| false":

```
<app-display [disabled]="(disabledStream$ | async) || false"></app-display>

```

It is also possible to configure the Angular Compiler options to switch off various checks.

e.g.

```
"angularCompilerOptions": { "strictNullInputTypes": false}

```

These are detailed in the Angular documentation - [Template Type Checking](https://angular.io/guide/template-typecheck#troubleshooting-template-errors).

The talk recording demonstrates the use cases for `ngAcceptInputType` and Set/Get, along with Input coercion, drawing from the experience of preparing the "ag-grid-angular" for use in strict applications.

Additionally the talk goes further and explains the user of generics.

```
export class GenericComponent<TData>{
    @Input()
    rowData: TData[] | undefined;

    @Output ()
    rowDataUpdated = new EventEmitter<TData]>();
}

```

Then:

```
rowData: number[] = [];
onRowDataUpdate (event: string[]) {}

```

And:

```
<app-generic
    [rowData]="rowData"
    (rowDataUpdated)="onRowDataUpdate($event)">
</app-generic>

```

As Inputs are a fundamental part of Angular this will impact every developer once their application enables strict mode. I would hate for developers to resort to any when there are Angular features to maintain fully typed components.

There is also an extended Q&A Session in the video.

## Code

Code examples for writing Angular Components that are compliant with Typescript strict mode. Two sample apps for the approaches described under [Template Type Checking](https://angular.io/guide/template-typecheck#troubleshooting-template-errors).

- GitHub Repo: [https://github.com/StephenCooper/StrictAngularComponents](https://github.com/StephenCooper/StrictAngularComponents)

In both demos you will see compilation errors when running `npm run start` as Stephen has left examples that need fixing following the approaches outlined.

## Related Reading

- Angular Template Type Checking Docs: [https://angular.io/guide/template-typecheck#template-type-checking](https://angular.io/guide/template-typecheck#template-type-checking)

## Slides

![Angular Kenya Meetup](https://blog.ag-grid.com/content/images/2022/06/StrictCompsStephenAnim.gif)

[Download pdf of the slides](https://drive.google.com/file/d/1JW84dsgh1xDSgMqGEIjkhkCHAWenFCw3/view?usp=sharing)

## Talk Recording

{% embed https://www.youtube.com/watch?v=5a2YKmVzMBM %}


[Watch On YouTube](https://www.youtube.com/watch?v=5a2YKmVzMBM)

<!--kg-card-end: markdown-->