What's new in Angular 5

whats-new-in-angular-5-header.png

Discover why Angular 5 is a great update and why you should be excited too.

Introduction

If you are a software developer there is a good chance you have heard about Angular. Angular is a JavaScript framework by Google that makes it easy to build Single Page Applications using JavaScript in a short amount of time and with less effort.

Angular has seen a lot of growth in just a few years and with Angular 2 completely rewritten from scratch, Angular has proven itself to be a great and efficient front-end framework.

In this article, we will go through a couple of things that have changed and some new things that were added in version 5 of Angular JS. You can see the full list of changes in the official changelog.

The important thing to note with this update is that many of the changes are under the hood and are targeted at making Angular faster, smaller and more optimised.

Angular 5 Now Supports TypeScript 2.4

TypeScript is a superset of JavaScript that allows static typing, classes and interfaces. TypeScript is supported by many IDEs and code editors and it makes it easy to catch errors while you type code. So what does this mean for Angular developers?

Well, with this support comes all the goodies of TypeScript 2.4 including, but not limited to:
– Stricter Type Checking.
– Strings in Enums.
– Stricter checks on “weak types”.

Read all about the improvements and changes in TypeScript 2.4 here.

For Angular 5, the compiler now operates as a TypeScript transform. This will generally make incremental builds faster. There were complaints about the amount of time it took projects to build, especially with large projects, and this update will improve the build time dramatically.

From version 2.3, TypeScript transforms were introduced. This feature allows Angular to hook directly into the TypeScript compilation pipeline thus ensuring custom builds specific to Angular.

To take advantage of this new feature, run your ng serve command with the --aot flag:

1$ ng serve --aot

The feature is optional but will be a default behavior in future releases of Angular CLI. The new feature is said to make build times on Angular 5 at least ‘95% times faster’ than previous versions.

Angular 5 Now Supports RxJS 5.5

Another component that has been updated in Angular 5 is RxJS. RxJS 5.5 introduced some newer features like Pipeable (“lettable”) operators.

This will improve tree shaking and make it easier to create custom operators. Although your code does not need to change, it would be useful to change to the new syntax as this would ensure smaller builds.

? “****Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of ES2015 module syntax, i.e. [**import**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) and [**export**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)**. The name and concept have been popularized by the ES2015 module bundler** rollup.” – Read more on tree shaking

Here is a sample of how you can use the new feature in RxJS 5.5:

1import { Component } from '@angular/core';
2    import { of } from 'rxjs/observable/of';
3    import { map, filter } from 'rxjs/operators';
4
5    @Component({
6      selector: 'app-root',
7      templateUrl: './app.component.html',
8      styleUrls: ['./app.component.css']
9    })
10    export class AppComponent {
11      title = 'app';
12
13      constructor() {
14        let someVar = of('foo', 'bar', 'baz', 'leaveout', 'leave me out too')
15
16        someVar
17          .pipe(
18            filter(value => value.length === 3),
19            map(value => value + ' world')
20          )
21          .subscribe(value => console.log(value))
22      }
23    }

As you can see, map and filter can now be called directly as functions. They can be imported from rxjs/operators. Also note how all the lettable operators are combined using the pipe method.

You can take a look at the list of RxJS 5.5 changes over the previous version here. You do not need to do anything to take advantage of RxJS 5.5. It comes as a default dependency in Angular 5.

Configurable “Preserve Whitespaces” Option

There is now a preserveWhitespaces option. This option is to be set in the tsconfig.json file and it removes white space characters from your templates code. This will lead to smaller builds. The option is false by default so setting it to true will turn it on for your application.

Here is a sample tsconfig.json file:

1{
2      "compileOnSave": false,
3      "compilerOptions": {
4        "outDir": "./dist/out-tsc",
5        "sourceMap": true,
6        "declaration": false,
7        "moduleResolution": "node",
8        "emitDecoratorMetadata": true,
9        "experimentalDecorators": true,
10        "target": "es5",
11        "typeRoots": [
12          "node_modules/@types"
13        ],
14        "lib": [
15          "es2017",
16          "dom"
17        ]
18      },
19      "angularCompilerOptions": {
20        "preserveWhitespaces": true
21      }
22    }

Notice that towards the bottom, in the angularCompilerOptions object, I have set the preserveWhitespaces value to true. This will in turn force white spaces to be stripped in my template code.

If you want to set this option on a per-component basis, you can set preserveWhitespaces to true in the @Component object. It does not seem like something anyone will want to use but you might like to know you can in case you need granular control:

1import { Component } from '@angular/core';
2    // ...
3
4    @Component({
5      selector: 'app-root',
6      templateUrl: './app.component.html',
7      styleUrls: ['./app.component.css'],
8      preserveWhiteSpaces: true
9    })
10    export class AppComponent {
11      title = 'app';
12
13      //...
14    }

Form Validation

In the new version of Angular, you can now specify when form validators should be executed. Previously, when a FormControl value changed, the validation was performed with every keystroke. This lead to poor performance when the validation was complex.

With the new update, you can specify the updateOn option. In this option, you can specify when the validation should be performed, with options like change, blur or submit. With this new control, you have more power over specifying how complex validations will be handled as opposed to handling it on every keystroke.

Using Template-driven Forms

When using template driven forms, you can set the validation options like this:

1<input name="username" ngModel="username" [ngModelOptions]="{updateOn:'blur'}">

You can also declare the options on the form tag like this:

1<form id="authForm" [ngFormOptions]="{updateOn:'submit'}" action="/login">
2        <!-- Other Input Stuff... -->
3    </form>

Using Reactive Forms

When using reactive forms, you can pass the updateOn property in the parameter object when you are instantiating the FormControl object.

Here is an example of how it can be done along with validators:

1this.username = new FormControl(null, {
2      updateOn: 'blur',
3      validators: Validators.required
4    ))

You can also do this on the Form level like so:

1this.authForm = new FormGroup({
2        username: new FormControl(null, {
3            updateOn: 'blur',
4            validators: Validators.required
5        )),
6        password: new FormControl(null, [
7            Validators.required   
8        ])
9    }, {
10        updateOn: 'submit'
11    })

Progressive Web Applications

Another area that has an update in Angular 5 is Progressive Web Applications (PWA). In previous versions of Angular, building PWAs were a little complex and there were many caveats that one needed to handle when developing and deploying Angular PWAs.

In Angular 5, creating a PWA is now easier than it used to be. Angular uses the module @angular/service-workers. Right now, PWA is not the default mode but it will be in future releases.

You can activate PWA support in your application by running the following command:

1$ ng set apps.0.serviceWorker=true

Goodbye Http, Hello

A new HttpClient was shipped in Angular 4.3 and it was an easier and more powerful way to make web requests. In version 5, Angular is deprecating the previous @angular/http library in favor of the HttpClient.

To use the new Httpclient, you’ll need to replace HttpModule with HttpClientModule from @angular/common/http. You will also need to inject the HttpClient service. If you were using map(res => res.json()) you’ll need to remove it as it’s no longer needed (JSON is the default response).

Here is a sample usage of the new HttpClient library:

1import { Injectable } from '@angular/core'
2    import { HttpClient } from '@angular/common/http'
3
4    @Injectable()
5    export class SomeService {
6        constructor(private http: HttpClient) {
7            this.http.get('/some/endpoint')
8        }
9    }

Support for Multiple Export Aliases

In Angular 5, you can now export your components with multiple names/aliases. A use case would be when developing packages and you would like to not have breaking changes:

1// ...
2    import { Component } from '@angular/core'
3
4    @Component({
5        selector: 'login-form',
6        templateUrl: './login-form.component.html',
7        exportAs: 'login, authform, authentication-form',
8    })
9    export class LoginFormComponent {
10        // ...
11    }

Router Events

The Angular router in version 5 now exposes more events during it’s lifecycle. You can use these events to further hook deeply into the Angular core and thus have more control of your application.

The new events are that are available to the Router lifecycle are:

  • *ActivationStart*
  • *ActivationEnd*
  • *ChildActivationStart*
  • *ChildActivationEnd*
  • *GuardsCheckStart*
  • *GuardsCheckEnd*
  • *ResolveStart*
  • *ResolveEnd*

Here is an example on how to subscribe to one of the router events:

1@Component({
2      // ... 
3    })
4    export class SampleComponent {
5        constructor(public router: Router) {
6            router.events.subscribe(event => {
7                if (event instanceof ActivationStart) {
8                    // Do something
9                }
10            });
11        }
12    }

Another small change to the Router is you can now instruct the page to reload when navigating to the same URL. You need to set the onSameUrlNavigation option to reload in the Router module options:

1RouterModule.forRoot(routes, {
2        onSameUrlNavigation: 'reload'
3    })

Internationalization Improvement

Previous versions of Angular used to rely on the browser APIs for currency, date and number formatting. However, this led to many inconsistencies and a growth of many polyfills due to different implementation across different browsers.

As a result, the Intl-API is no longer supported. Now, localisation is based on data from the Unicode Common Locale Data Repository (CLDR). Since this is a central repository, the formatting should now be consistent and browser independent and will remove the need for polyfills.

From Angular 5.0.0 the pipes now use this custom implementation custom implementation. You should check out this document that compares the pipe behaviour between version 4 and version 5.

⚠️ You can still use the old **Intl-API** by importing the **DeprecatedI18NPipesModule** after the **CommonModule** but using a deprecated API is not recommended and should be avoided.

The default locale that is loaded is English (en-US). If you want to change the current locale, to Spanish for instance, you have to specify the locale and import it:

1import { registerLocaleData } from '@angular/common';
2    import { localeEs } from '@angular/common/locales/es';
3    import { LOCALE_ID } from '@angular/core';
4
5    registerLocaleData(localeEs);
6
7    // ....
8
9    @NgModule({
10        providers: [{provide: LOCALE_ID, useValue: 'es'}]
11        // ...
12    })
13    export class AppModule {
14        // ...
15    }

Animations in Angular 5

Animations in Angular 5 also got a bit of an upgrade. Animations can now animate based on numeric value changes by using :increment and :decrement. Basically you can set an animation whenever an element data numeric value is increased or decreased!

Here is an example of the added syntax used in a sample component:

1@Component({
2        animations: [
3            trigger("increaseNumber", [ 
4                transition(':increment', [ 
5                    // ...
6                ]),
7                transition(':decrement', [
8                    // ...
9                ]),
10            ])
11        ],
12        template: `<div>Number Update <span [@increaseNumber]="number"></span></div>`
13    })
14    class SomeComponent() { 
15        number = 1;
16    }

Breaking Changes from Angular 4 to Angular 5

While there are some nifty features and optimisations introduced in Angular 5, there are also some breaking changes that have been introduced. You should go through the list below to see if you are affected before updating your application to use Angular 5.

Here are some features broken/deprecated by Angular 5:
enableLegacyTemplate is no longer used by default in the compiler. You should use the ng-template element and not template. Angular 6 will remove the support for <template> completely.
@angular/http has been marked as deprecated in favor of the more optimised @angular/common/http module.
– The ReflectiveInjector for Dependency Injection (DI) has been deprecated in favor if StaticInjector.
OpaqueToken has been removed in favor of InjectionToken.
ErrorHandler no longer has a parameter constructor.
– The ng-container element must now be used in place of i18n comments.
– In the Router, the initialNavigation option now only accepts enabled and disabled. The use of previous values like true, false, legacy_enabled and legacy_disabled has been discontinued.

Most applications should be fine after upgrading though, as there are not too many breaking changes. Check out this tool. It’ll help you upgrade from your current version to a newer Angular version.

Conclusion

Angular 5 is a great update and it is recommended that you update your applications to use it. The update comes with very useful tools that will definitely make your application build faster and generally more optimised.

A more comprehensive list of the changes is available in the official changelog.