Angular 8 was just released!
As planned, there were no surprises: the update of the framework and CLI can be done by using ng update and the new features are a welcome addition in line with the motto “evolution instead of revolution”.
In this article, I will cover the most important new features of Angular 8 and the corresponding Angular CLI 8.
TypeScript 3.4
Angular 8.0 now supports TypeScript 3.4, and even requires it, so you’ll need to upgrade.
You can checkout out what TypeScript 3.3 and TypeScript 3.4 brings on the Microsoft blog.
Breaking change in ViewChild and ContentChild
There is a breaking change in the usage of ViewChild and ContentChild, which unfortunately didn’t always show a consistent behavior in the past. While they were used in earlier versions for a component to request an element not inside a structural directive like ngIf or ngFor, the query result was already available in ngOnInit. Otherwise, the program code could access it at the earliest in ngAfterViewInit (or ngAfterContentInit forContentChild). For elements that were only loaded into the DOM at a later time due to data binding, the program code had to insert ngAfterViewChecked or, respectively, ngAfterContentChecked.
As this behavior was confusing, the component must now specify when the resolution should take place:
@ViewChild('info', { static: false
})
paragraph: ElementRef;
If static has the value true, Angular tries to find the element when initializing the component. This only works if it is not in a structural directive. When using static: false, the resolution takes places after initiating or refreshing the view.
The command ng update automatically tries to enter the correct value here. If that is not possible, it adds a comment with a TODO in its place.
Queries with the related decorators ViewChildren and ContentChildren are not affected by this change. They have always exhibited a dynamic behavior in the sense of static: false.
Differential loading
Your Angular 8 apps will now be automagically more performant, thanks to differential loading.
Until now, it was common to compile applications to good old ECMAScript 5, since this “JavaScript of our fathers” runs almost anywhere today. This means that both IE 11 and the web crawler behind the Google search engine can execute the program code.
However, the new ECMAScript 2015 and its subsequent versions are more efficient: these versions allow more compact bundles and the browser can also interpret them more efficiently. Since it was previously common to retreat to ECMAScript 5 as the smallest common denominator, other modern browsers, unfortunately, couldn’t use these advantages.
This ends now: starting with version 8, the CLI includes a feature that is named differential loading. The idea behind it is to provide two groups of bundles: one is based on ECMAScript 5 and addresses older browsers, the other is based on a younger ECMAScript version, e.g. ECMAScript 2015, and offers modern browsers the mentioned advantages.
There isn’t much you need to do in order to activate differential loading: all that is necessary is to set an upper and a lower bar for the ECMAScript versions to be supported. The upper bar is entered in the tsconfig.json as follows:
"target": "es2015"
The lower bar, on the other hand, is defined by a browserslist. It is a file that identifies many browsers to be supported, according to certain criteria like market shares. They can be stored e.g. in the file browserslist, which the CLI meanwhile creates in projectroot when generating a new project:
> 0.5%
last 2
versions
Firefox ESR
not dead
IE 9-11
In the illustrated case, the browserslist points to ECMAScript 5 browsers with the entry IE 9–11. Thereby, the CLI determines the lower bar as this version. If the CLI receives the instruction to create a build (ng build), compiling and bundling processes will take place for both versions:
Build for differential loading
The disadvantage of this process becomes obvious here: the time required for the build process is doubled.
The different browsers can now decide which version of the bundles to load. For this, they receive the scriptreferences in the index.html additions: those pointing to ECMAScript 5 bundles receive the addition nomodule. This prevents browsers with support for ECMAScript modules, and thereby ECMAScript 2015 and newer, from ignoring the reference. The ECMAScript 2015+ bundles, on the other hand, are implemented by the CLI via type=”module”. Thus, older browsers will ignore these script tags:
<script src="main-es2015.js"
type="module"></script>
<script src="main-es5.js"
nomodule></script>
In contrast to ng build, all other CLI commands use only (!) the upper bar. In the illustrated case, that is ECMAScript 2015. This happens, among others, for efficiency reasons: especially during debugging and testing, developers want to see a result as soon as possible without being required to wait for a second build.
You don’t have to do anything special to benefit from differential loading, the ng build
command with the --prod
flag will take care of bundling everything so that differential loading is working out of the box:
$ ng build --prod
Ivy
Ivy is obviously a huge part of this release, and it took most of the effort from the team these last month. There is so much to say about Ivy that I wrote a dedicated article about it.
TL;DR: Ivy is the new compiler/runtime of Angular. It will enable very cool features in the future, but it is currently focused on not breaking existing applications.
Angular 8.0 is the first release to officially offer a switch to opt-in into Ivy. There are no real gains to do so right now, but you can give it a try to see if nothing breaks in your application. Because, at some point, probably in v9, Ivy will be the default. So the Angular team hopes the community will anticipate the switch and provide feedback, and that we’ll catch all the remaining issues before v9.
We tried it on several of our apps and already caught a few regressions, so we would strongly advise to not use it blindly in production 😄.
If you feel adventurous, you can add "enableIvy": true
in your angularCompilerOptions
, and restart your application: it now uses Ivy! Check our article and the official guide for more info.
Bazel Support
One of the new features of Angular 8 is the possibility to (more easily) build your CLI application with Bazel.
Bazel is a build tool developed and massively used by Google, as it can build pretty much any language. The Angular framework itself is built with Bazel.
The key advantages of Bazel are:
- the possibility of building your backends and frontends with the same tool
- the incremental build and tests
- the possibility to have remote builds (and cache) on a build farm
Service worker
Registration strategy
The service worker registration has a new option that allows to specify when the registration should take place. Previously, the service worker was waiting for the application to be stable to register, to avoid slowing the start of the application. But if you were starting a recurring asynchronous task (like a polling process) on application bootstrap, the application was never stable as Angular considers an application to be stable if there is no pending task. So the service worker never registered, and you had to manually workaround it. With the new registrationStrategy
option, you can now let Angular handle this. There are several values possible:
-
registerWhenStable
, the default, as explained above -
registerImmediately
, which doesn’t wait for the app to be stable and registers the Service Worker right away -
registerDelay:$TIMEOUT
with$TIMEOUT
being the number of milliseconds to wait before the registration - a function returning an Observable, to define a custom strategy. The Service Worker will then register when the Observable emits its first value.
For example, if you want to register the Service Worker after 2 seconds:
providers: [
ServiceWorkerModule.register('/ngsw-worker.js', {
enabled: environment.production,
registrationStrategy: 'registerDelay:2000'
}),
// ...
]
Bypass a Service Worker
It is now also possible to bypass the Service Worker for a specific request by adding the ngsw-bypass
header.
this.http.get('api/users', { headers: { 'ngsw-bypass': true } });
Multiple apps on sub-domains
Previously, it was not possible to have multiple applications using@angular/service-worker
on different sub-paths of the same domain, because each Service Worker would overwrite the caches of the others… This is now fixed!
Forms
markAllAsTouched
The AbstractControl
class now offers a new method markAllAsTouched
in addition to the existing markAsDirty
, markAsTouched
, markAsPending
, etc. AbstractControl
is the parent class of FormGroup
, FormControl
, FormArray
, so the method is available on all reactive form entities.
Like markAsTouched
, this new method marks a control as touched
but also all its descendants.
form.markAllAsTouched();
FormArray.clear
The FormArray
class now also offers a clear
method, to quickly remove all the controls it contains. You previously had to loop over the controls to remove them one by one.
// users
is initialized with 2 users
const users = fb.array([user1, user2]);
users.clear();
// users is now empty
Dynamic imports for lazy routes
Lazy-loaded routes now use the standard dynamic import syntax instead of a custom string. This means that TypeScript and linters will be better able to complain when modules are missing or misspelled.
So a lazy-loaded import that looked like this:
{ path: '/cart', loadChildren: './cart/cart.module#CartModule' }
Will now look like this:
{ path: /cart
, loadChildren: () => import(./cart/cart.module
).then(m => m.CartModule) }
The change in syntax will be taken care of for you if you’re using the ng upgrade
command to upgrade your app.
New features for ngUpgrade
Up until now, one problem in the hybrid operation of AngularJS 1.x and Angular with ngUpgrade has been that the routers of both frameworks have at times been dueling over the URL. This led to side effects that were difficult to comprehend. In order to avoid this, the possibility of using the identical Location service for accessing the URL in both framework versions has been added.
To achieve this, the Angular team has extended the possibilities of Angular’s Location services and thereby provided a substitute for $location in AngularJS.
For this reason, the new method onUrlChange for monitoring URL changes, among other modifications, has been added in the Location service:
export class
AppComponent {
constructor(loc: Location, pLoc: PlatformLocation) {
loc.onUrlChange((url) => console.debug('url change', url));
console.debug('hostname: ', pLoc.hostname);
}
}
The PlatformLocation service offers additional access to the individual parts of the URL. A detailed description on how the $location substitute, which is based on it, is used for a better interlacing of both frameworks, can be found here. Additionally, there you can now find an idea for lazy loading of AngularJS, which is based on the aforementioned dynamic ECMAScript imports.
CLI workflow improvements
The CLI is continuing to improve, and now the ng build
, ng test
and ng run
are equipped to be extended by 3rd-party libraries and tool. For example, AngularFire already makes use of these new capabilities with a deploy
command
Deprecated APIs and Features
Angular aims to balance innovation and stability in their framework and to do that they have removed or replaced some features & API’S so that Angular can stay updated with latest practices, changing dependencies, or changes in the platform itself.
To make these transitions easy they deprecate APIs and features for a period of time before removing them which provide developers time to update your apps to the latest APIs and best practices.
- Web Tracing Framework integration
-
@angular/platform-webworker
and@angular/platform-webworker-dynamic
both the packages are deprecated - Usage for any in TesBed.get
- Removed deprecated DOCUMENT from
@angular/platform-browser
- @angular/http removed from the list of packages
- ngForm element selector
- Service worker versionedFiles
Angular Performance & Upgradtion from Angular 7 to Angular 8
Angular 8 new features are nice, but the main reason for many of us to upgrade to new versions of Angular 8 is to get a performance boost. If you worked with previous angular versions then upgrading an app from Angular 7 over to Angular 8 is simple.
For most developers, one command should take care of this update :
ng update @angular/cli @angular/core
Angular Firebase
Angular have officially added support for firebase and now we can deploy our application using the Angular CLI.
ng run [PROJECT_NAME]:deploy
Builders API
The new version allows us to use Builders API. It uses builders for main operations like: serve, build, test, lint and e2e. Basically, the builder Builders are functions that implement the logic and behavior for a task that can replace a command which you pass to the createBuilder() method from @angular-devkit/architect package & now we can create our custom builders as well.
import { BuilderOutput, createBuilder } from '@angular-devkit/architect';
export default createBuilder((options, context) => {
return new Promise<BuilderOutput>(resolve => {
resolve({ success: true });
});
});
AngularJS API Migration Improvements with $location service
The Angular Team wants to provide support for all developers using AngularJS to upgrade them with latest Angular so some enhancements have been made to provide better integration with the AngularJS $location service in hybrid (AngularJS <=> Angular) apps. A new package angular/common/upgrade
is added help you
- To retrieve the state from location service.
- To track all location changes.
- Help you retrieve hostname protocol port search properties which were available in AngularJS.
- MockPlatformLocation API added to test the location service.
Conclusion
Summing up all the above features, The Angular team has certainly did a great with the framework making developers job much easier & simpler. Angular version 8 looks like a much more accessible solution focused on the modern technological trends added features like Ivy, route configurations use dynamic Imports, new builder API in the CLI, web worker support, Unified Angular Location Service & with every new release, the framework is getting smoother and smoother making the Angular platform better.
Next Steps
Now that you have learnt the implementation of Firebase push notifications in Ionic 4, you can also try
- Ionic 4 PayPal payment integration — for Apps and PWA
- Ionic 4 Stripe payment integration — for Apps and PWA
- Ionic 4 Apple Pay integration
- Twitter login in Ionic 4 with Firebase
- Facebook login in Ionic 4 with Firebase
- Geolocation in Ionic 4
- QR Code and scanners in Ionic 4 and
- Translations in Ionic 4
If you need a base to start your next Ionic 4 app, you can make your next awesome app using Ionic 4 Full App
Top comments (0)