Behind The Code Magazine - Special Edition #1

Page 1

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1

1


INTERVIEW

BARTŁOMIEJ NAROŻNIK Senior Analyst Developer and Scrum Master

“I ALWAYS LOOK FOR A WAYS TO SELF IMPROVE”

Bartek is a developer for over 11 years. Experienced both in frontend and backend technologies. Worked for biggest polish and european companies. Actively involved in Warsaw Angular community. In his work combining technical knowledge with social skills. Constantly looking for a challenge. Living by the rule, a day when you learn nothing is a lost one day’

Can you tell us something about yourself? Like, who are you and what do you do?

I am a software developer with over 11 years of professional experience. I Work in JavaScript. NET and Technologies. Currently with more focus on Angular. I also train people about Angular and I help with migrating AngularJS 1.x applications to Angular.

so my toys were always missing some parts after I tried to disassemble it and assemble again. It’s the same with computers and applications. And it’s still so much to be done in this area. Angular is just one example. Technology that wasn’t even there 7 years ago. And that’s only If we count AngularJS.

What made you choose the path of a programmer/techie?

Is that what you dreamed of doing?

2

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1

I guess it’s just something that is really cool for me. Since I’ve got my first computer back in 90s I was very interested of how it works. Actually my parents say that I was always interested of how things work

There are many things that I dream doing. I guess programming is one of them. But definiely I love programmming and I wouldn’t change it to anything else.


INTERVIEW BARTŁOMIEJ NAROŻNIK If you had to choose a different profession, what would it be?

There are two areas that attract me in my professional career. One is self development. But rather being better at something than learning new stuff (it doesn’t always have to be the same). The second is creating something new. One of my other passions is music so maybe I would be some singer, guitar player (and music composer). Guess we’ll find out when computers take over the world and there will be no need for programmers anymore.

Do you think that software rules the world? I’m pretty sure that pills rule the world. But probably there is some software used in the process of making them... It’ll be easier to answer that question when computers finally take over the world...

How do you think technology (software) will evolve?

We always do a software only for one reason. To help us doing something or do it for us. Technology helps us with so many things right now and it’s just beginning. Computers are getting smarter and closer to us. I hope in the future they will be doing most of the boring or hard stuff. As for the software there are so much of new technologies emerging that we will be busy for the long time.

What is your favourite technology?

I don’t think I have a favourite. I’ve been working with a lot of technologies by now and each new one is just better that previous I’ve been working with.

ce that it will not be some something short-lived.

How did you like NgPoland 2017?

From speaker perspective it’s a really good place to be. The Cinema hall was huge and the screen was pretty impressive. It feels awesome to be on the stage like this. The level of sessions was really great and there is a lot of inspiration for me. A lot new ideas that I could use in my projects.

What motivates you?

I always look for a ways to self improve. Having new challenges and being able to reach new goals is something that I aim for. And of course we’re not doing what we do only for ourselves. If there is at least one person that you can help or that can start to love something you love, it’s extremely motivating.

What is your favourite film and book?

My favourite book is ‚Dune’ by Frank Herbert. The world and all the relations described there is on so grand scale that it’s just amazing. I have a lot of favourite films but if I was to choose one just now it would be ‚Inside Man’ by Spike Lee. One of the few times that I was me amazed during the whole movie.

What music do you listen to?

I listen to a lot of rock music. Sometimes soft rock, sometimes hard. Depends on my mood. And my favourite band is only one. I’ve never missed a concert of Alter Bridge in Poland.

Why Angular?

Some years ago we were looking for some good frontend framework. Back then AngularJS was a framework that took javascript on the next level. In time I’ve found out that there is big and dynamic community of Angularians. A lot of people that love Angular and also serious companies behind the framework which gives confiden-

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1

3


CODE

ANGULAR 5 HAS ARRIVED

Angular 5.0.0 has arrived We all have been waiting for this. Angular 5 is there with some new features. It’s quite a tight schedule, which Angular team had set for themselves. Twice a year there is new major version released. There have been over 1900 commits between versions 4 and 5. Almost 9 commits per day. The Team keep focus on making Angular smaller, faster and easier to use. At least that’s the tagline. The update from AngularJS to Angular 2 was a huge change and a huge step forward, but the cost of that was lack of backwards compatibility. But it will be like that to more. Angular 4 brought us some new features keeping backward compatibilit y and the team guarante e tha t ea c h n ew maj o r ve r si o n w i l l b e b a c k w ar d c o mp atib l e w i th p r ev i o u s o n e. The upgrade to Angular 5 is as well quite painless. Many changes have been done invisibly for the developer. However some breaking chan-

4

ges have been included but of course if it’s breaking or not depends on to what extent have you been using Angular in your applications. Also for all developers who kept their code bases up to date, the changes should not be difficult to handle.Let’s see what they’ve got for us.

Angular Compiler There have been some significant improvements to Angular Compiler. It provides faster rebuilds by supporting incremental compilation. There are new features available for decorators and code bundles can now be smaller by removing whitespaces from templates.

Incremental Compilation TypeScript 2.3 introduced a feature called TypeScript transforms. That allowed Angular to hook into TypeScript’s compilation pipeline. Rebuilds are now significantly faster and that’s because only the part of application that is related to changed

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1


CODE ANGULAR 5 HAS ARRIVED code needs to be recompiled. With the new feature you can expect around 40% drop of rebuild time. And it can get even better. When performing an incremental AOT build of https://angular.io, itsaves 95% of the build time with the new compiler pipeline (dropped from more than 40 seconds to less than 2 seconds on their development machines). To use it simply run ng serve with aot flag:

ng serve --aot It will become default eventually, yet there are some known speed issues for projects containing more than thousand components. So as soon as the development team solves those issues making sure the function works well regardless the project size we can expect having it turned on by default. As a result of using transforms, we don’t need genDir anymore. Also outDir has changed, so now generated files for packages in node modules are emitted.

Preserve Whitespace Since now all tabs, spaces and newlines in the templates have not been touched by the compiler and put as they are into bundle file. Now you can choose whether to preserve them or not. You can configure it globally for module:

platformBrowserDynamic(). bootstrapModule(AppModule, { preserveWhitespaces: false }); Or you can specify it application wide in your tsconfig.js

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1

{

”extends”: „../tsconfig.json”, ”compilerOptions”: { ... }, ”angularCompilerOptions”: { „preserveWhitespaces”: false }, ”exclude”: [ ... ] } There is also flag per component:

@Component({ selector: ‚home’, templateUrl: ‚./home.component.html’, preserveWhitespaces: false }) export class HomeComponent { } But if you want to make sure, your whitespaces will be there you can use directive

<div ngPreserveWhitespaces> whitespaces preserved here <span> and here </span> </div> As well as new expression &ngsp;

<a>Spaces</a>&ngsp;<a>between</a> &ngsp;<a>links.</a> It looks like   with a typo, but do not get fooled. It’s a special expression, Angular compiler will change to whitespace. Note that there can be only one consecutive space, meaning that if you use more than one   in a row, it will be transformed to a single space by compiler. And of course what happens inside <pre> tags stays there, so those will not be affected by whitespace cleaning mechanism.The gain of that flag

5


ANGULAR 5 HAS ARRIVED CODE depends on your application but in average it should give you about 6% less code. Quite useful if you take into account that it’s just one flag. Currently preserve Whitespace flag defaults to true in all cases, so it’s not a breaking change. But in the future the team hopes to change the default value to falseso it could save space for developers by default.

Improved Decorator Support You can now use values calculated at runtime in decorators for useValue, useFactory and data in object literals. You can also use lambda instead of named functions, which allows executing code without affecting your d.ts files.

Component({ provider: [{provide: SOME_TOKEN, useFactory: () => null}] }) export class SomeClass {} Component({ provider: [{provide: SOME_TOKEN, useValue: SomeEnum.OK}] }) export class SomeClass {}

Many names for components Your directives and components can now have more than one name. It could be useful to avoid breaking changes when doing migration. This feature has been used as a part of the Angular Material project in its prefix migration. For example:

@Directive({ selector: ’[app-dashboard]’, exportAs: ’dashboard, wallboard’ }) Can be used as:

6

<div app-dashboard #foo=”dashboard”> <!-- or --> <div app-dashboard #foo=”wallboard”>

StaticInjector replaces ReflectiveInjector ReflectiveInjector has been replaced by StaticInjector. The new injector does not require Reflect polyfil contrary to old one. That of course reduces application size. So now instead:

ReflectiveInjector.resolveAndCreate (providers); There will be:

Injector.create(providers);

Zone improvements There has been zones speed improvement in this release of Angular. Moreover it is now possible to bypass zone at all which could be useful for performance focused applications. You can bypass zones by bootstrapping application with ‘noop’ as ngZone.

platformBrowserDynamic().bootstrapModule(AppModule, {ngZone: ‘noop’}) .then( ref => {} );

Native addEventListener for faster rendering Angular 5 is now using the Javascript’s native addEventListener method to register events. This gives a lot of performance improvement for complex Angular applications where there are lots of event bindings. Angular did make many assumptions about its event handlers. As a result the bookkeeping for native addEventListener is significantly cheaper than Zone’s addEventLister which can’t make such assumptions.

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1


CODE ANGULAR 5 HAS ARRIVED Template validation Previously in Angular templates were not validated which means that if you were having some typo or some syntax error you would know about it only at runtime. To address this problem you can now use fullTemplateTypeCheck option to enable template validation in compiler. Using this option, compiler will throw an error when using pipe with wrong argument type:

<div>{{ 11.1 | lowercase }}</div> -> Argument of type ‚11.1’ is not assignable to parameter of type ‚string’ Also local variables referencing a directive will be analysed

<input [(ngModel)]=”book.title” required #bookCtrl=”ngModel”> <div *ngIf=”bookCtrl.hasror(’required’)”> Title required</div> -> Property ‚hasEror’ does not exist on type ‚NgModel’. Did you mean ‚hasError’? Right now the default value of fullTemplateTypeCheck is false, but we can expect to see it become true in a future release. (Side note: this feature is currently a bit flaky. I ran into some issues while testing it. You might want to wait 5.0.x to try it!).

Angular CLI Angular 5 ships with the new version of CLI 1.5. This means that CLI 1.5 will generate Angular 5.0.0 projects by default.

Build Optimizer The build optimizer is a tool included in CLI that makes your bundles smaller. It has two main jobs. First is to mark parts of the application as pure (without side effects). If the function is marked as pure, and its result is used nowhere, it means that this function can be safely removed from the

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1

bundle. This improves the tree shaking provided by the existing tools.Second job of build optimizer is to remove Angular decorators from application’s runtime code. Those decorators are consumed during compilation, thus aren’t needed at the runtime and can be safely removed.Each of those two jobs decreases the size of your application also making the boot speed of application faster for the users. With CLI 1.5 the build optimizer is turned on by default so every developer can benefit from smaller bundles. However it can be disabled using flag --no-build-optimizer.

Configuration updates There are small changes of how tsconfig.json files are used by Angular CLI. It’s to follow TypeScript standards. Until 5.0.0 lazy loaded routes were automatically added if you were manually specifying a list of files or include in tsconfig.json file. Now – to follow TypeScript specification – it’s no longer done. Since by default CLI does not use files or include sections, most developers will not be affected by this change.

Angular Universal Angular Universal is a project that helps developers to perform server side rendering of Angular applications. While rendered on the server, application can then be bootstrapped on the top of generated HTML. This is quite useful when in need to deal with scrapers and crawlers that don’t support JavaScript. It can also increase the perceived performance of application.

State Transfer API In Angular 5, there are two new modules: ServerTransferStateModule and the corresponding BrowserTransferStateModule. Those modules allow generating data as a part of server side rendering and then transferring it to the client. It’s quite useful in scenarios when application fetches data over HTTP. Transferring state from the server allows limiting number of HTTP requests from the client, because calls made server-side don’t have to be made client side.

7


ANGULAR 5 HAS ARRIVED CODE DOM support

JSON is the default format (no need to parse).

Angular Universal now uses Domino - https:// github.com/fgnass/domino (and removes dependency on Parse5). With this change, platform-server also exposes a DOCUMENT and nativeElement that is closer to the client. Using Domino gives more DOM manipulations support out of the box within server side context. It also improves support for 3rd party JavaScript and Component libraries that are not server-side aware.

//After http.get(path); //Or http.get<MyType>(path);

HttpClient One of the new features of Angular 4.3 was HttpClient class in @angular/common. It has a lot of useful features.Response body can now be typed:

interface Book { id: number; title: string; } interface BookResponse { books: Array<Book>; } export class BookService { public get() { return this.http.get<BookResponse> (BOOKS_ENDPOINT) .map(response => response.books); } }

8

//Before http.get(path).map(res => res.json());

The Request and Response objects are immutable. There are events available for upload and download progress tracking.

//book.service.ts export class BookService { public post(payload) { return new HttpRequest(’POST’, URL, payload, { reportProgress: true, }) } } // book.component.ts bookService.post(payload).subscribe(event => { if (event.type === HttpEventType.UploadProgress) { const percentage = Math.round(event. loaded/event.total*100); console.log(`${percentage}% uploaded.`); } else if (event instanceof HttpResponse) { console.log(’Upload completed!’); }; });

It also gives post-request verification and flush based testing framework. Finally for HttpClient you can add interceptors which allows some middleware logic to be inserted into the pipeline.

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1


CODE ANGULAR 5 HAS ARRIVED import { HTTP_INTERCEPTORS } from ’@angular/common/http’; import { SimpleInterceptor } from ’./simple. interceptor.ts’; @NgModule({ providers: [{ multi: true, provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor }], }) export class AppModule {} // ./simple.interceptor.ts import {Injectable} from ’@angular/core’; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from ’@angular/common/http’; @Injectable() export class SimpleInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req); } } In 5.0.0 the new HttpClient has become recommended for all application and the old @angular/http package is now deprecated. In order to update to HttpClient, you’ll need to replace HttpModule with HttpClientModule from @angular/common/http in your modules, inject the HttpClient service, and remove any map(res => res.json()) calls, which are no longer needed. In this release there is also one additional feature to HttpClient. You can now use object literals instead of HttpHead and HttpParams classes.

// with classes

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1

const headers = new HttpHeaders().set (’X-Option’, ’true’); http.get(url, { headers }); const params = new HttpParams().set(’test’, ’true’); http.get(url, { params }); // without classes http.get(url, { headers: {’X-Option’: ’true’} }); http.get(url, { params: {’test’: ’true’} });

Router

The Angular Router has gained new events so now developers can track the cycle of the router from the start of running guards through to completion of activation. New events (in sequence) are GuardsCheckStart, ChildActivationStart, ActivationStart, GuardsCheckEnd, ResolveStart, ResolveEnd, ActivationEnd, ChildActivationEnd. So now, for example, you can display some spinner to the user when the route is being changed.

class MyComponent { constructor(public router: Router, spinner: Spinner) { router.events.subscribe(e => { if (e instanceof ChildActivationStart) { spinner.start(e.route); } else if (e instanceof ChildActivationEnd) { spinner.end(e.route); } }); } }

I18n

Angular 4 relied on the browser to provide i18n data (like number, date, currency format). It was using Intl API which required polyfill to work for some browsers. This resulted in inconsistencies across browsers and some common formats (like currency) didn’t work as expected for some browsers.In Angular 5 all the pipes have been updated and reimplemented to use own implemen-

9


ANGULAR 5 HAS ARRIVED CODE tation and rely on CLDR (Unicode Common Locale Data Repository). CLDR provides key building blocks for software to support the world’s languages. It’s the largest and most extensive standard repository of locale data. For detailed information please look at the document comparing the pipe behaviour between v4 and v5. By default locale data in Angular is now set for the language en-US. But it can be easily changed to another:

import {LOCALE_ID} from ’@angular/core’; import {registerLocaleData} from ’@angular/common’; import localePl from ’@angular/common/locales/pl’; registerLocaleData(localePl); @NgModule({ providers: [ { provide: LOCALE_ID, useValue: ’pl’ } ] }) export class AppModule { }})

All i18n pipes now have additional last parameter locale which allows you to override locale and use it instead of the one defined in the token LOCALE_ID. Old pipes are still available in DeprecatedI18NPipesModule.

import { NgModule } from ’@angular/core’; import { CommonModule, DeprecatedI18NPipesModule } from ’@angular/common’;

Don’t forget that you will still need to import the Intl API polyfill if you want to use those deprecated pipes.

Date Pipe As a result of switch to CLDR there are some breaking changes in date pipe. The predefined formats (short, shortTime, shortDate, etc.) use now thepatterns from CLDR instead of those from Intl API. For example short date for en-US will be 11/21/17 instead of 11/21/2017. The narrow version of the week day is now EEEEE instead of E, the format E is now similar to EE and EEE. The narrow version of months is now MMMMM instead of L, the format L is now the short standalone version of months. The narrow version of eras is now GGGGG instead of G, the format G is now similar to GG and GGG. The timezone z will now fallback to O and output GMT+1 instead of the complete zone name (e.g. Pacific Standard Time). The reason is that the quantity of data required to have all the zone names in all of the existing locales is too big. The timezone Z will now output the ISO8601 basic format, e.g. +0100, you should now use ZZZZ to get GMT+01:00. Below all the breaking changes in the form of table: Field type Eras Months Week Day Timezone

Format Narrow Narrow Narrow Long location

Example value v4 v5 A for AD O OOOOG S for September L MMMMM M for Monday E EEEEE Pacific Standard Time z NOT AV.

Timezone

Long GTM

GTM+01:00

Z

ZZZZ

@NgModule({ imports: [ CommonModule, // import deprecated module after CommonModule DeprecatedI18NPipesModule ] }) export class AppModule { }})

There is support for some new formats: - New predefined formats long, full, longTime, fullTime. - Format yyy will result in three digits zero padded year, e.g. the year 47 will be formatted as 047 and the year 2017 will be 2017. - Standalone months with the formats L to LLLLL. - Week of the year with the formats w and ww, e.g. weeks 7 and 07. - Week of the month with the format W, e.g. week 5.

10

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1


CODE ANGULAR 5 HAS ARRIVED - Fractional seconds with the format S to SSS. - Day periods for AM/PM with additional formats aa, aaa, aaaa and aaaaa. The formats a to aaa are similar and aaaa is the wide version if available (ante meridiem/post meridiem), or equivalent to a otherwise, and aaaaa is the narrow version (a/p). - Extra day periods with the formats b to bbbbb (and B to BBBBB for the standalone equivalents), e.g. morning, noon, afternoon, .... - The short non-localized timezones with the format O to OOOO. The formats O to OOO will output GMT+1 while the format OOOO will be GMT+01:00. - The ISO8601 basic time zones with the formats Z to ZZZZZ. The formats Z to ZZZ will output +0100, while the format ZZZZ will be GMT+01:00 and ZZZZZ will be +01:00.The date pipe will now work exactly the same across all browsers. That will fix a lot of bugs for safari and IE. Finally eras can now be used on their own without the date, e.g. the format GG will be AD instead of 11 21, 2017 AD.

Currency Pipe The default value for symbolDisplay is now symbol instead of code. So by default you will see $4.99 for en-US instead of USD4.99.

und to, the local format will be used (and it usually rounds numbers to 0 digits, instead of not rounding previously), e.g. {{ 3.141592 | percent }} will output 314% for the instead of 314.1592% previously. // p = 3.1415926535 {{ p | percent }} {{ p | percent: ’4.5-5’ }}

// outputs: ’314%’ // outputs: ’0,314.15927%’

{{ p | percent: ’4.5-5’: ‚pl’ }} // outputs: ’0 314,15927%’

Forms updateOn There is significant performance improvement for Angular Forms. You can now run validation and update values on ‘blur’ or ’submit’ instead of on every input event. That’s important especially when you have any server side validations in your application. You can now also specify ‘asyncValidators’ directly in options objects, rather than specifying it as a third parameter.

Reactive Forms For the reactive forms, the updateOn property is passed on in parameter object in FormControl constructor.

The second parameter of the currency pipe (symbolDisplay) is no longer a boolean. Now it takes the values: code, symbol or symbol-narrow. A boolean value is deprecated, but it’s still valid for now - will print a warning message in the console.

this.title = new FormControl(null, { validators: Validators.required, updateOn: vblur’ });

Choosing between code, symbol and symbol-narrow gives you access to more options for some currencies:

This can also be done for FormGroups and FormArray meaning that it will be applied for all form controls inside the group.

// c = 4.5495 {{ c | currency }} {{ c | currency: ’CAD’ }} {{ c | currency: ’CAD’: ‚code’ }}

this.header = new FormGroup({ title: new FormControl(), author: new FormControl() }, { updateOn: ’submit’ });

// outputs: ’$4.55’ // outputs: ’CA$4.55’ // outputs: ’CAD4.55’

{{ c | currency: ’CAD’: ‚symbol-narrow’: ’1.2-2’: ‚pl’ }} // outputs: ‚4,55 $’

Percent Pipe

The contained elements can override update event

There is one breaking change for percent pipes. If you don’t specify the number of digits to ro-

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1

11


ANGULAR 5 HAS ARRIVED CODE this.header = new FormGroup({ title: new FormControl(null, { validators: Validators.required, updateOn: ’change’ }), author: new FormControl(null, [Validators. required]) }, {updateOn: ’submit’})

Template Driven Forms

to make it easier to develop.

New transition aliases In addition to the :enter and :leave transition aliases the new :increment and :decrement aliases can be used to shorten numerical value change transitions.

//Before transition(’0 => 1, 1 => 2, 2 => 3, 3 => 4’, ...)

The same applies for forms that are defined viatemplate. This is done by ngModelOptions.

//After transition(’:increment’)

<input type=”text” ngModel [ngModelOptions]=”{updateOn: ’submit’}”>

Disabling animations

And here as well this setting is inherited from the container element.

<form [ngFormOptions]=”{updateOn: ’submit’}”> <input name=”title” ngModel type=”text”> <input name=”author” ngModel type=”text”> </form> Although subordinate element can override the value, similarly like for reactive forms.

<form [ngFormOptions]=”{updateOn: ’submit’}”> <input name=”title” ngModel type=”text” [ngModelOptions]=”{updateOn: ’select’}”> <input name=”author” ngModel type=”text”> </form>

Animations Angular 5 brings several syntax extensions for animations. Animation engine is now more powerful, more complex and has some additional validation

12

Animations can now be activated and deactivated using values which are associated with data binding. To do this, the .disabled property of the trigger value is bound.

@Component({ animations: [ trigger(”val”, [ /* ... */ ]) ], template: `<div [@val]=”expression” [@val. disabled]=”isAnimationDisabled”>` }) class MyComponent() { ”expression” = ‚’; isAnimationDisabled = false; } The @.disabled property now works without anexpression. When the expression is missing it will treat the property as true.

<!-- Animation will be disabled here --> <div @.disabled> <div [@animate]=”expression”>Animate</ div> </div>

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1


CODE ANGULAR 5 HAS ARRIVED Negative limit Previously, when animating subordinate elements, it was only possible to limit the selection to a certain number of elements that were counted from the start. Now it’s also possible to limit elements counting from the end. In order to do so you have to set negative limit value which refer to the last X elements. In the example below the selection is limited to last 5 elements with class “item”:

trigger(”anim”, [ transition(”:enter”, [ query( ”.item”, [ /** ... **/ ], { limit: -5 } ) ]) ])

Animations validation Angular will now report errors in case it finds any discrepancies in the CSS while binding. This includes invalid CSS syntax and properties. Previously it was not reported and could lead to unexpected behaviour like replicating html elements on the page. So now for a code like that:

export const expandTypo = [ trigger(’expandTypo’, [ transition(’:leave’, [ animate(’150ms cubic-bezier(0.4, 0.0, 1, 1)’, style({ height: 0, opacty: 0 // <-- typo here, could also be anything random })) ]) ]) ];

You’ll get a nice message:

>Error: The animation trigger „expandTypo” has failed to build due to the following errors: The provided animation property „opacity” is not supported CSS property for animations at InjectableAnimationEngine.AnimationEngine. registerTrigger (animation engine next.is:50) at eval (animation renderer.is:64) at Array.forEach (<anonymous>) at AnimationRendererFactory.createRender (animation renderer.is:64) at DebugRendererFactory2.createRender (services.is:887) at createComponentView (view.is:228) at callWithDebugContext (services.is.843) at Object.debugCreateComponentView [as createComponentView] (services.is:168) at createViewNodes (view.is:288) at createRootView (view.is:210)

RxJS 5.5 Angular 5.0.0 supports RxJS 5.5 or later. The important change in this release of RxJS allows avoiding the side effects of import mechanism used previously. The new way is called “lettable operators”. It eliminates the side effects of the tree shaking (code splitting) problems that were affecting previous method of importing operators (“patch” method).

//Before import { Observable } from ’rxjs/Observable’; import ’rxjs/add/operator/map’; import ’rxjs/add/operator/filter’; shortTitles = allBooks .map(book => book.title) .filter(title => title.length < 20); //After import { Observable } from ’rxjs/Observable’; import { map, filter } from ’rxjs/operators’; shortTitles = allBooks.pipe( map(book => book.title), filter(title => title.length < 20), );

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1

13


ANGULAR 5 HAS ARRIVED CODE The other change that RxJS 5.5 brings is that it now distributes a version using ECMAScript modules. It allows saving considerably on bundle size. Angular CLI will use this version by default, but if you’re not using Angular CLI, you can find more details in Build and Treeshaking section of the lettable operators documentation.

Now, if you try to assign an object that does not have any common property to weak type, you’ll get a compiler error.

TypeScript 2.4 support

const options = { hideMenu: true };

Angular 5 brings support for TypeScript 2.4. Below some of the main features of TypeScript 2.4.Members of an enum can now be expressed with a string instead of number.

checkOpts(options); // Error checkOpts(options as Options); // No error

Function checkOptions(opts: Options) { // … }

Progressive Web Applications enum BookForms {Novel = “NOVEL”, Fable = “FABLE”, Poem = “POEM”,} However in this regard string enums cannot be mapped backwards like their number-based relatives. Therefore a query like BookForms [“Novel”] isn’t possible to catch the string “Novel”. Newer version of TypeScript improves type checking for generics, but also makes inferences for the return type of a call. This can improve your experience and catch some errors. An example of new errors you may now encounter:

let x: Promise<string> = new Promise(resolve => { resolve(21); // Error! }); Another new feature of TypeScript is called Weak Type Detection. Any type that contains only set of all-optional properties is considered to be weak. Here’s an example of such type:

interface Options { prefix?: string, timeout?: number, maxResults?: number }

14

Development of Progressive Web Applications (PWA) in Angular 4 was a complex and elaborated process. It was difficult to handle and also not fully stable. In Angular 5 the development of PWA was simplified and made more accessible both to developer and user. Angular CLI will give the ability to create configuration code on its own. However there is no support in CLI yet. It’s been planned for version 1.6. Angular package @angular/service-worker wraps the major functionality of browser service workers. It also requires the generation of the HTML5 caching manifest and the creation of an application shell. The package allows creating mobile web application that have the features of native mobile applications, like offline capability, push notifications giving additionally the update flow.

Caching Angular Service Worker package provides caching. By default it can cache your static assets. But it can go further, allowing to cache external resources (like fonts, icons from a CDN…), route redirection and even dynamic content caching (like calls to your API). There are different strategies possible (always fetch for fresh data, or always serve from cache for speed…). It provides really smart network optimizations, requiring only some JSON configuration from us.

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1


CODE ANGULAR 5 HAS ARRIVED Push Notifications We can easily subscribe or send push notification using Service Worker module. It does not require any setup in configuration file. An example of subscription to push notifications:

import { SwPush } from ’@angular/service-worker’; subscribeToPush() { // Requesting messaging service to subscribe current client (browser) this.swPush .requestSubscription({ serverPublicKey: this.VAPID_PUBLIC_KEY }) .then(pushSubscription => { // Passing subscription object to our backend this.pushService.addSubscriber (pushSubscription) .subscribe( res => { console.log(’[App] Add subscriber request answer’, res); } ); }); } }

version until page reload. This is a well-known trade-off for PWA applications. You’ve probably seen already websites showing information like: “There is a newer version available, would you like to refresh?”.Fortunately Service Worker module allows us to receive information that newer version is available and perform update in the right moment. Below and example code of such activity.

import { SwUpdate } from ’@angular/service-worker’; this.swUpdate.checkForUpdate() .then(() => { console.log(’[App] checkForUpdate completed’) }) this.swUpdate.activateUpdate() .then(() => { console.log(’[App] activateUpdate completed’) this.winRef.nativeWindow.location. reload() }) With the newer version of our application, the Service Worker will only download what has changed, allowing incredibly fast application start!

Update flow There are two core principles about update of PWA applications. The user workflow cannot be interrupted by unexpected update. Application version should remain the same in the opened browser tab until it’s closed or refreshed by the user. There has to be also an integrity of application maintained. Meaning that if there was any change in application code, we treat that as new version and do not update it for the user unless informed. Downside of such approach is that the application will not be updated immediately. User will still see older

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1

15


ANGULAR 5 HAS ARRIVED CODE Breaking changes The following APIs had already been marked as “deprecated” in Angular 4 and in Angular 5 have been removed: - The OpaqueToken has been removed, instead you have to use InjectionToken. - The parameter constructor of the ErrorHandler has been removed. - ngOutletContext has been removed from NgTemplateOutlet. - The Angular Router takes only “enabled” and “disabled” as values for the parameter initialNavigation. The values “true”, “false”, “legacy_enabled” and “legacy_disabled” are no longer accepted.

- The option useDebug for the compiler has been removed. It had no effect and was deprecated since v4. - NgFor has been removed as it was deprecated since v4. Instead use NgForOf. This does not impact the use of *ngFor in your templates. - TrackByFn was deprecated since v4 and it has been removed. Use TrackByFunction instead. - NgProbeToken has been moved from @angular/ platform-browser to @angular/core. It was deprecated in the former package since v4. - PRIMITIVE has been removed in @angular/platform-webworker as it was deprecated since v4. Use SerializerTypes.PRIMITIVE instead.

- RouterOutlet properties locationInjector and locationFactoryResolver have been removed as they were deprecated since v4. - The ng-container element must now be used instead of i18n comments. - The compiler no longer uses the enableLegacyTemplate by default, since in Angular 4 the <template> element was deprecated and <ng-template> should be used instead. The <template> element and the enableLegacyTemplate option will be removed in Angular 6. - The @angular/http module has been marked as deprecated and it’s to be replaced by the new @angular/common/http module. - The ReflectiveInjector for dependency injection is now deprecated. Instead, the StaticInjector is used. - The method ngGetContentSelectors() has been removed as it was deprecated since v4. Use ComponentFactory.ngContentSelectors instead.

16

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1


CODE ANGULAR 5 HAS ARRIVED Conclusion Angular 5.0.0 is a major release that brings significant enhancements to developer production, compilation performance, and application bootstrapping performance. The tagline for this release is „smaller, faster, easier to use” and it described this release quite well. Your application compiled code can be now smaller with the features like whitespace removal, build optimizer, removal of i18n polyfills, removal of reflect polyfill, usage of RxJS 5.5 and others. Your applications and compilation will now be faster because of TypeScript transform support, bundle size improvements, zone improvements, using native eventListener, forms updateOn parameter and many more.Angular is also more powerful and easier to use. Changes like AOT all of the Time, AOT for Tests (historically Tests had to be made in JIT mode, because of bootstrapping dynamically), additional DOM Support for Universal, new i18n pipes, improved decorator support and many more will help to create your applications with less time and more functionality.

Useful web resources Here’s a bunch of web resources you may find useful when upgrading to Angular 5 in your projects: - Post about Angular 5.0.0 release on official angular.io blog - Changelog for version 5.0.0 on Angular repository - Angular Update Guide (list the changes you have to make in your application when migrating be tween versions) - Angular Service Worker exploration by Maxim Salnikov: part 1 and part 2.

There are a lot of new features in this release of Angular. And it’s been only around seven months since version 4.0.0 and one and a half months since version 4.4 is there. So the rate of changes is pretty impressive. So start making even better Angular applications using 5.0.0 and we’ll look forward for next major release which is planned for March/April 2018.

BEHIND THE CODE MAGAZINE SPECIAL EDITION #1

17


18

BEHIND BEHINDTHE THECODE CODEMAGAZINE MAGAZINESPECIAL SPECIALEDITION EDITION#1#1


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.