Last Updated: August 16, 2018
·
8.894K
· whatishedoing

Avoid the Safe Navigation Operator in Angular

The Safe Navigation Operator, AKA the Elvis Operator, can help reduce code by ensuring that an object is not null before accessing a property of it. Consider this class and component:

class ElvisTest {
    public key = true;
}

@Component({
    moduleId: module.id,
    selector: 'elvis-test',
    templateUrl: 'elvis-test.component.html'
})
export class ElvisTestComponent {
    @Input() elvisTest?: ElvisTest;
}

Since an instance of ElvisTest is passed to the component as an Input, it could possibly remain undefined. As such, we could use the Elivs operator to prevent UI errors:

<div>{{elvisTest?.key}}</div>

However, this operator will also handle undefined properties, meaning this also works:

<div>{{elvisTest?.unknownKey}}</div>

This can become a huge problem when refactoring code. If ElvisTest is modified as follows:

class ElvisTest {
    public renamedKey = true;
}

... an AoT compiler will still happy compile the template, and not throw an error to inform us that we are accessing a non-existent property! Plugins for IDEs such as VS Code also will not warn of this problem.

To prevent this, try and ensure that your properties are non-nullable where possible -- use e.g. Redux over inputs where possible -- and avoid the Elvis operator:

<!-- Output element with no content. -->
<div>{{elvisTest && elvisTest.renamedKey}}<div>

<!-- Hide element entirely. -->
<div *ngIf="elvisTest">
    {{elvisTest.renamedKey}}
<div>