Discover why Angular 5 is a great update and why you should be excited too.
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.
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.
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.
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 }
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.
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>
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 })
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
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 }
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 }
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 })
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 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 }
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.
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.