New in Angular 4 - Improved Reactive Programming Support

If we have a look at the Angular core roadmap, one of the main items is the continuous improvement of the support for building Angular Applications in Reactive style.

The main feature in Angular 4 is the improved AOT support, allowing our applications to become much smaller.

But there are a couple more new features on this release that will really help us write programs in a more reactive style, if we want to use that approach.

What on a first look could seem like a small improvement in template syntax (ngIf related) turns out to be an important improvement towards writing applications in a more reactive style.

Let's first have a look first at the improvements on ngIf in isolation. So what has changed ?

NgIf Improvements

With Angular 4, we can now add an else clause to ngIf, which was not available before. Let's have a look at what this looks like:

As we can see, we can now specify in ngIf an else clause with the name of a template, that will replace the element where ngIf is applied in case the condition is false.

This would either print "Condition is true" or the content of the loading template to the element annotated with ngIf, depending on the truthiness of the condition.

Another improvement on ngIf

So this is already really handy for many cases. So what other improvements does this syntax have ? We can also evaluate the truthiness of an expression, and assign the result of the expression (which might not be a boolean) to a variable.

Let's have a look at an example:

The template above would print "Angular For Beginners", because the expression course is truthy. As we can see, course corresponds to a component property which is a plain Javascript object.

But the result of the expression is not a boolean, its an object and it gets assigned to a local template variable named result, and so the description property gets printed to the screen as expected.

These are two great extra features for building our templates, but in what way do they help also to improve the support for reactive programming ?

It has to do with the async pipe, and the way we can use it to build reactive programs.

The async Pipe early functionality in Angular

Let's give a simple example, imagine that we have a CourseService, that brings some data asynchronously from the backend, using for example the Angular HTTP module:

Let's also have a look at what the Course custom type looks like:

As we can see, its made out of two mandatory properties id and shortDescription, and three more optional properties that are annotated with a question mark.

Let's say that now our application loads this data from the backend and we want to display it on the screen (all the course properties). Here is what our component would look like:

So what is happening here ? Let's break it down:

  • we are defining an Observable member variable named courseObs, that is initially undefined
  • we are initializing courseObs with an Observable that is returned by the service layer
  • we don't know when the Observable will return or what it will return, other than it should be a Course instance

So here is how we can to display this data on the screen: we would want to use the Angular async pipe.

Why use the async pipe ?

Because it automatically subscribes and unsubscribes from Observables as the component gets instantiated or destroyed, which is a great feature.

This is especially important in the case of long-lived observables like for example certain Observables returned by the router or by AngularFire.

Also because it makes our programs easier to read and more declarative, with less state variables in our component classes.

For example, notice that the component above only has an observable member variable, and that we don't have direct access to the data at the level of the component itself - only the template accesses the data directly.

So let's then use the async pipe to print the course details to the screen:

As we can see, this ends up not being very convenient, because we need to use the async pipe multiple times. Actually this would cause multiple subscriptions, which could lead to other problems and also its not as readable.

So in practice this is what we often ended up doing instead to avoid these issues:

As we can see, we have subscribed to the observable returned by the service layer, and defined a local variable that contains the result of the backend call. Now our template is a lot simpler: we simply have a variable named course that we can use to access the data.

But there could be a couple of potential problems with this especially in a larger application.

What are some potential problems with this approach ?

This approach works great, but one potential issue is that now we have to manually manage the subscriptions of this Observable.

In the case of HTTP observables this does not have impact because those Observables emit only once and then they complete, but in the case of long-lived Observables this could potentially cause an issue.

Another potential issue with this approach

Also we have defined here a local variable to pass data to the template, which ends up making our program more imperative if compared to the more reactive approach of simply defining an Observable, passing it to the template and declaring on the template how to use it.

Because now we have here the state stored on this variable at the level of the component, we might be tempted to further write code that mutates that state.

Here in this small example it would not cause an issue, but in a larger application this approach could potentially cause some maintainability problems.

By using the async pipe we where looking to write a program in a more reactive style where those couple of potential problems are avoided by design. So let's see if we can still do that.

Another alternative - refactor into a smaller component

Or alternatively, we could also move the course detail implementation to a new component. This would allow us to keep using the async pipe, and avoid the manual subscription at the level of the component:

And this is what the course-detail component would look like:

This is a good alternative, because we might end up using this component in other places of the application.

But we ended up needing to create a separate component mostly to avoid having to use the async pipe multiple times in the parent template.

In Angular 4 there is now a much better way and it ties back to the ngIf new features: let's have a look.

Improved reactive programming support in Angular 4

If we combine all the available features of ngIf in Angular 4 with the async pipe, we can now come up with the following solution:

So what is going on in this example ? Let's break it down:

  • the async pipe is being used to subscribe only once to courseObs
  • the else clause is defining what to display while the data is not available (the ng-template named loading)
  • the 'as' syntax is specifying a template variable for the expression courseObs | async, and that variable is named course
  • the result of this expression is the data stream of courseObs
  • now there is a course variable available inside the ngIfsection

Advantages of this more reactive approach

As we can see in Angular 4 we can now simply combine the async pipe with the new ngIf features, and have all the features combined:

  • There are no manual subscriptions at the component level for observables coming out of the service layer
  • we don't have to create smaller components to be able to use the async pipe only once and prevent multiple subscriptions
  • no local data state variables are defined at the level of the component, so its less likely to run into issues caused by mutating local component state
  • we now have a more declarative code: both the component and the template are very declarative, we are simply plugging in together streams of data instead of storing local variables and passing them to the template
  • We end up with a very readable template

Conclusions

As we could see in this example, the new ngIf features although useful in many other cases, are especially useful when combined with the async pipe for simplifying the development of Angular applications in a more reactive style.

I hope you enjoyed the post, I invite you to have a look at the list of other similar posts and resources on Angular below:

Video Lessons Available on YouTube

Have a look at the Angular University Youtube channel, we publish about 25% to a third of our video tutorials there, new videos are published all the time.

Subscribe to get new video tutorials:

Other posts on Angular

If you enjoyed this post, have also a look also at other popular posts that you might find interesting: