Check out myAngular article series with live demos and Facebook group Angular - Advanced Topics

Save Navigation Operator in Angular

Torgeir "Tor" Helgevold
- JavaScript Developer and Blogger
Published: Thu Dec 31 2015

Angular is now a lot less forgiving about undefined references in binding expressions than Angular 1.x is. In this post I will show how to use the safe navigation operator to safe guard against undefined references in view templates.

Angular has introduced much stricter expression evaluation, so unlike in Angular 1.x, you will actually get “cannot read property 'x' of undefined” errors if you're not careful when creating template expressions.

I support this change, but there are very common scenarios where the data we want to bind to the view is undefined temporarily. One example of this is template rendering in combination with ajax calls.

Since the data call is asynchronous there is a period of time where the data is expected to be undefined. However, the Angular expression engine doesn't know this by default, so it throws an error.

There are a few ways to address this including defensive 'undefined' checks or making sure objects always have initial values. Both of these are valid, but feel a bit cumbersome compared to Angular 1.x.

Luckily the Angular team has recognized this and added support for the safe navigation operator. The purpose of the safe navigation operator is to allow us to specify bindings where the bound data will become available at a later time.

Take the sample below:

this.http.get('./customer.json').map((res: Response) => { this.customer = res.json(); return this.customer; }) .flatMap((customer) => this.http.get(customer.contractUrl)).map((res: Response) => res.json()) .subscribe(res => this.contract = res); <div>Customer: {{customer?.name}}</div> <div>Product: {{contract?.product}}</div>

Here I am binding customer.name and contract.product to the view, but obviously the values are not available until the http calls complete.

By specifying a '?' between the object and the property I am telling Angular to evaluate if contract/customer is defined before evaluating the binding. When the value resolves the binding will be updated by the change tracking.

This falls under the category of syntactic sugar, but it's super helpful in avoiding extra boilerplate code.

If you liked this article, share it with your friends on social media:

We also have a new Facebook group about advanced Angular topics.

I invite you to follow me on twitter