by Gerard Sans | @gerardsans
by Gerard Sans | @gerardsans
Spoken at 75 events in 23 countries
900
1.4K
Angular Academy
X . Y . Z
MAJOR MINOR PATCH
Future ready
2016
Stable and performant
4.2 Animations
New angular.io website
4.3 HttpClient
2017
Smaller, Faster and Easier to use
PWA support
SSR. Material components
Bazel. Build time tools
2017
Smaller, Faster and Easier to use
Webpack 4. RxJS 6. TS 2.7
Angular Elements. Ivy Renderer
Tooling improvements
2018
preserveWhitespaces false by default
// BEFORE
@Component({
template: `<my-element #my-element></my-element>`
})
class MyComponent {
@ViewChild('my-element') myElement:ElementRef;
ngAfterViewInit() {
this.myElement.nativeElement; // type is "any"
}
}
app/my.component.ts
// AFTER
@Component({
template: `<my-element #my-element></my-element>`
})
class MyComponent {
@ViewChild('my-element') myElement:ElementRef<MyElement>;
ngAfterViewInit() {
this.myElement.nativeElement; // type is “MyElement”
}
}
app/my.component.ts
Add Webpack v4 support
Support for upgrades
ng update --next
Ability to specify budgets for your apps
bundle, initial, allScript, all, anyScript, any
baseline, max, min, warning, error
bytes, KB, MB, %
15th Feb
Add Webpack v4 final
Upgrade to webpack-dev-server v3
Support aditional Lazy Load Modules
Support for prepackaged schematics
{
"compilerOptions": {
"experimentalDecorators": true,
...
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"preserveWhitespaces": false,
"enableResourceInlining": true,
"enableIvy": true,
}
}
tsconfig.json
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent { }
app/app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `<hello></hello>`,
styles: [`p { font-family: Lato; }`]
})
export class AppComponent { }
app/app.component.ts
do throw switch finally
tap throwError switchAll finalize
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/filter';
const isOddNumber = (x: number) => x%2!==0;
Observable.interval(1000)
.filter(isOddNumber);
// --0--1--2--3--4--5-- interval
// -----1-----3-----5-- filter
src/app.component.ts
import { interval } from 'rxjs';
import { filter } from 'rxjs/operators';
const isOddNumber = (x: number) => x%2!==0;
interval(1000).pipe(
filter(isOddNumber)
);
// --0--1--2--3--4--5-- interval
// -----1-----3-----5-- filter
src/app.component.ts
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
import 'rxjs/add/observable/finally';
Observable.throw("💩").subscribe({
error: e => l(`Error: ${e}`)
})
Observable.throw("💩")
.catch(e => of("No worries. Sorted!😃"))
.finally(() => { /* code */ })
.subscribe(v => l(v));
src/app.component.ts
import { throwError } from 'rxjs';
import { catchError, finalize } from 'rxjs/operators';
throwError("💩").subscribe({
error: e => l(`Error: ${e}`)
})
throwError("💩").pipe(
catchError(e => of("No worries. Sorted!😃")),
finalize(() => { /* code */ }),
).subscribe(v => l(v));
src/app.component.ts
// <div [@fade]="fade" fast></div>
// <div [@fade]="{ value: fade, params: { type: 'fast' }}">
const hasAttribute = (attribute: string) =>
(fromState: string, toState: string,
element: any, params: {[key:string]: any}
): boolean =>
element.hasAttribute(attribute) || (params && params.type==attribute);
}
export const fade = trigger('fade', [
state('fadeIn', style({ opacity: 1 })),
state('fadeOut', style({ opacity: 0.1 })),
transition(hasAttribute("fast"), animate('100ms linear')),
transition('fadeIn <=> fadeOut', animate('400ms linear')),
]);
animations.ts
export class HelloComponent {
version: FormControl = new FormControl('6.0.0', Validators.required);
form: FormGroup = new FormGroup({ v: this.version });
constructor() {
this.form.statusChanges // VALID INVALID PENDING DISABLED
.subscribe(status => console.log(status));
this.version.markAsPending(); // emits PENDING
this.version.markAsPending({onlySelf: true}); // no output
this.version.markAsPending({emitEvent: false}); // no output
}
}
app/hello.component.ts