Non-null Assertion Operator in Angular
Tags: angular, typescript
Published: 2021-03-31 21:45:39

---
title: Non-null Assertion Operator in Angular
published: true
description: How and when to use the non-null assertion operator in Angular.
tags: Angular, TypeScript,
//cover_image: https://direct_url_to_image.jpg
---

If your team has been following [best practices guidelines](https://blog.angular.io/with-best-practices-from-the-start-d64881a16de8) put out by the Angular team (& adopted by the community as a whole), you may have made the decision to implement Strict Mode for TypeScript in your codebase.

```json
//tsconfig.json
{
  "compileOnSave": false,
  "compilerOptions": {
    ...
    "strict": true, //woooo strict mode
  },
  "angularCompilerOptions": {
    "enableIvy": true,
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}
``` 

You may have encountered a new error in Angular `Property 'myClassMember' has no initializer and is not definitely assigned in the constructor.ts`

If you weren't using a lot of (or any) of the flags for configuring stricter TypeScript parsing previously, you may see new "errors" like this as you code. 

*Note, these are not _"new errors caused by TypeScript"_ but instead _"already existing potential errors in your codebase that the stricter TypeScript flags are now catching"_ - this is an __IMPORTANT__ mental shift for your team to make. TypeScript is here to help us write better code and catch potential errors, not to make our lives as developers harder. 

The "has no initializer and is not definitely assigned" error is due to the [`strictPropertyInitialization`](https://www.typescriptlang.org/tsconfig#strictPropertyInitialization) flag being set to true as a part of Strict mode, and is checking to ensure any class property declared is not null. In Angular, we are typically declaring properties on our classes when we encounter this error. The TypeScript compiler is reviewing our class members, and if it does not see our class member being given a value _when it's declared_ or if our member is not given a value _in the constructor function_, it thinks that member is null, and rightfully so! 


This is a common occurrence in Angular where we often initialize our members in the component's lifecycle hooks - which TypeScript is unaware of. TypeScript doesn't know that our `ngOnInit` function will run after the component is initialized. 


```TypeScript
import { Component, OnInit } from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  // defined when initialized
  public myInitiallyDefinedMember = "beep";

  // defined in the constructor method
  public myConstructorDefinedMember: string;

  // defined in the ngOnInit Lifecycle hook
  // will throw TypeScript error
  public myLifecycleDefinedMember: string;

  constructor() {
    this.myConstructorDefinedMember = "bop";
  }

  ngOnInit() {
    this.myLifecycleDefinedMember = "boop";
  }
}
```

Will throw the error: 

```bash
Error in src/app/app.component.ts (16:10)
Property 'myLifecycleDefinedMember' has no initializer and is not definitely assigned in the constructor.
```

To let TypeScript know we're going to initialize `myLifecycleDefinedMember` in our component, we can use the [Non-null Assertion Operator](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator), or a `!`. 

```TypeScript
import { Component, OnInit } from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  ...
  // defined in the ngOnInit Lifecycle hook, 
  // now using the Non-null Assertion Operator
  public myLifecycleDefinedMember!: string;

  ngOnInit() {
    this.myLifecycleDefinedMember = "boop";
  }
}
```


The above example is an appropriate use-case, this does NOT mean: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1t6wsa94xkzf548glz8.jpg)


To see how strict mode affects typings & assertions, open this StackBlitz example, and in the `tsconfig.json` file remove line 14 `"strict": true`. 

{% stackblitz angular-non-null-assertion-operator %}

## Key Take Away 

You should ONLY use the Non-null Assertion Operator when you know you will be setting a value for a component member. If there are instances where you aren't sure if a member has a value, it is better practice to use the optional operator.