SlideShare a Scribd company logo
Angular
Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
Angular
Architecture for scalable Angular applications
Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
Angular
Architecture for scalable Angular applications
Scalable architecture for Angular applications
Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
Angular
Architecture for scalable Angular applications
Scalable architecture for Angular applications
with introduction to Angular
Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
Angular
Architecture for scalable Angular applications
Scalable architecture for Angular applications
with introduction to Angular
and more
Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
Agenda
@AboutMe()
Angular 2+ Paradigms Promise & array
The Pattern
Architecture
Demo
Q&A
Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
Agenda
@AboutMe()
Angular 2+ Paradigms Promise & array
The Pattern
Architecture
Demo
Q&A
Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
@AboutMe()
• I started programming 19 years ago
• I code for money from the 10 years
• I code for Decerto ~4 years
• I was programming in Pascal, C, PHP, Javascript, Bash, SQL, C++, Java,
Typescript
• I did some AJAX before it was popular
• I did some UX before it was so popular
• I did some Devops before it was so named
• I was programming SPAs over the last 5 years in AngularJS
• I observe the development of Angular 2 since AngularJS 1.5-beta.0
• I am doing SPA in Angular 2–5 from version 2.1.0
Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
@AboutMe()
• I started programming 19 years ago
• I code for money from the 10 years
• I code for Decerto ~4 years
• I was programming in Pascal, C, PHP, Javascript, Bash, SQL, C++, Java,
Typescript
• I did some AJAX before it was popular
• I did some UX before it was so popular
• I did some Devops before it was so named
• I was programming SPAs over the last 5 years in AngularJS
• I observe the development of Angular 2 since AngularJS 1.5-beta.0
• I am doing SPA in Angular 2–5 from version 2.1.0
Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
Angular 2+
crash course
How to not write a large or scalable web applications.
Toy project
• npm install --global @angular/cli@latest # first time only
• ng new toy-project # first time only
Typescript (open app.component.ts)
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'app works!';
}
ES2015 import modules Exported symbol from module Module in node_modules
Decorator
(not an annotation!)
POJO
ES2015 export modules
Syntactic sugar for
Object with prototypal inharitance
String property on instance
Toy project – Count to a random number
Toy project – Count to a random number
AppComponent
CounterComponent
RandomNumberGeneratorService
Plain old button
Toy project – Count to a random number
• Create counter component
• Create Random Number Generator Interface
• Define the inferface
• Create a RNG Service
• Implement counter
• Generate random number
• Handle click
Toy project – create counter component
• npm run ng -- generate component --inline-style --inline-template
counter
Typescript (open counter.component.ts)
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-counter',
template: `
<p>
counter Works!
</p>
`,
styles: []
})
export class CounterComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
Template string
Constructor
Method Interface
Toy project – create interface
• npm run ng -- generate interface random-number-generator
Typescript (replace random-number-generator.ts)
export interface RandomNumberGenerator {
readonly name: string;
readonly infoUrl: string;
next (state: any): {state: any, value: number};
reset (seed?: any): any;
}
Readonly property… …of type string
Return type
OptionalMethod signature Value of any type
(Simpliest ever random number generator)
(Simpliest ever random number generator)
https://xkcd.com/221/
Toy project – create service
• npm run ng -- generate service xkcd-rng
import {Injectable} from '@angular/core';
import {RandomNumberGenerator} from './random-number-generator';
@Injectable()
export class XkcdRngService implements RandomNumberGenerator {
readonly infoUrl = 'https://xkcd.com/221/';
readonly name = 'XKCD Random Number Generator';
reset() {
return null;
}
next(state: any = null) {
return {state, value: 4};
}
}
Typescript (replace xkcd-rng.service.ts)
Default value
Property shorthand
Toy project – implement counter
Angular (replace counter.component.ts)
import {Component, Input, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'app-counter',
template: `{{ tick | async }}`,
})
export class CounterComponent {
@Input() counter = 5;
@Input() delay = 90;
@Output() finish = new EventEmitter<boolean>();
@Output() tick = new EventEmitter<number>();
public start(): void {
this.count(0);
}
private count(n: number): void {
this.tick.emit(n);
if (n >= this.counter) {
this.finish.emit(true);
} else {
setTimeout(() => this.count(n + 1), this.delay);
}
}
}
How to not write a large or scalable web applications.
It will count to 5
unless you specify
otherwise
It will be placed in <app-counter> element
It will display current tick number whenever it comes
It’s a component
It will wait 90ms
between ticks
unless you specify
otherwise
It will tell you about finish
It will tell you about tick
You can start counting down
Look! There is no $apply!
Toy project – generate random number
Angular (replace app.component.ts, add XkcdRngService in providers in AppModule)
import {Component, OnInit} from '@angular/core';
import {XkcdRngService} from './xkcd-rng.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
counter: number;
constructor(public xkcd: XkcdRngService) {
}
ngOnInit(): void {
this.counter = this.xkcd.next().value;
}
}
Dependency injection
Assigned to component
if public/private specified
Lifecycle hook
providers: [
XkcdRngService,
],
Toy project – handle click
Angular (replace app.component.{html,css})
<section>
<button (click)="cnt.start()">Start</button>
<h2>
<app-counter #cnt
[counter]="counter"></app-counter>
</h2>
</section>
h2 {
display: inline-block;
margin: 0;
}
button {
margin: 10px;
padding: 10px;
}
Input in app-counter Property from app-root
Handle output
Local template variable
- definition and usage
Access target component API
Styles are connected to
the component instance,
so…
Toy project – (quick demo)
Paradigms:
imperative vs declarative
computation in the loop
for vs forEach
const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
// for
for (let i = 0; i < array.length; ++i) {
console.log(array[i]);
}
// forEach
array.forEach((item) => console.log(item));
for vs map
const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
// for
const doubled1 = [];
for (let i = 0; i < array.length; ++i) {
let double = array[i] * 2;
doubled1.push(double);
}
// map
const doubled2 = array.map((item) => 2 * item);
for vs filter
const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
const isPrime = (n) => ...; // true or false
// for
const primes1 = [];
for (let i = 0; i < array.length; ++i) {
if(isPrime(array[i])){
primes1.push(array[i]);
}
}
// filter
const primes2 = array.filter(isPrime);
for vs reduce
const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
// for
let sum1 = 0;
for (let i = 0; i < array.length; ++i) {
sum1 = sum1 + array[i];
}
// reduce
const sum2 = array.reduce((last, item) => last + item, 0);
for vs reduce
const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
const add = (a, b) => a + b;
// for
let sum1 = 0;
for (let i = 0; i < array.length; ++i) {
sum1 = add(sum1, array[i]);
}
// reduce
const sum2 = array.reduce(add, 0);
map-filter-reduce
const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
const double = (x) => 2 * x;
const isPrime = (n) => ...;
const add = (a, b) => a + b;
const doubled2 = array.map(double);
const primes2 = array.filter(isPrime);
const sum2 = array.reduce(add, 0);
map-filter-reduce
const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
const double = (x) => 2 * x;
const isPrime = (n) => ...;
const add = (a, b) => a + b;
const doubled2 = array.map(double);
const primes2 = array.filter(isPrime);
const sum2 = array.reduce(add, 0);
Primitive value, array, promise, …
…
Primitive value, array, promise, …
number
Array
<number>
Promise
<number>
?
Single Multiple
Now
In future
Primitive value, array, promise, …
number
Array
<number>
Promise
<number>
?
Single Multiple
Now
In future
Primitive value, array, promise, …
number
Array
<number>
Promise
<number>
?
Single Multiple
Now
In future
Primitive value, array, promise, …
number
Array
<number>
Promise
<number>
Observable
<number>
Single Multiple
Now
In future
promise vs observable
promise
.then( (value) => console.log(value))
.catch( (reason) => console.error(reason))
.finally(() => console.log('Done'));
observable.subscribe(
(value) => console.log(value),
(reason) => console.error(reason),
() => console.log('Done')
);
promise vs observable
promise
.then( (value) => console.log(value))
;
observable.subscribe(
(value) => console.log(value)
);
promise vs observable
promise
.then((value) => console.log(value));
observable
.subscribe((value) => console.log(value));
promise vs observable
promise
.then((value) => console.log(value));
observable
.subscribe((value) => console.log(value));
Primitive value, array, promise, observable
number
Iterable
<number>
Promise
<number>
Observable
<number>
pull semantics
push semantics
Single Multiple
Now
In future
Observable - rxMarble
http://reactivex.io/assets/operators/legend.png
Debounce operator
Merge operator
Concat operator
Map operator
Filter operator
RxJS operators
audit, auditTime, buffer, bufferCount, bufferTime, bufferToggle,
bufferWhen, catchError, combineAll, combineLatest, concat, concatAll,
concatMap, concatMapTo, count, debounce, debounceTime, defaultIfEmpty,
delay, delayWhen, dematerialize, distinct, distinctUntilChanged,
distinctUntilKeyChanged, elementAt, every, exhaust, exhaustMap, expand,
filter, finalize, find, findIndex, first, groupBy, ignoreElements,
isEmpty, last, map, mapTo, materialize, max, merge, mergeAll, mergeMap,
flatMap, mergeMapTo, mergeScan, min, multicast, observeOn,
onErrorResumeNext, pairwise, partition, pluck, publish, publishBehavior,
publishLast, publishReplay, race, reduce, repeat, repeatWhen, retry,
retryWhen, refCount, sample, sampleTime, scan, sequenceEqual, share,
shareReplay, single, skip, skipLast, skipUntil, skipWhile, startWith,
switchAll, switchMap, switchMapTo, take, takeLast, takeUntil, takeWhile,
tap, throttle, throttleTime, timeInterval, timeout, timeoutWith,
timestamp, toArray, window, windowCount, windowTime, windowToggle,
windowWhen, withLatestFrom, zip, zipAll
map-filter-reduce --- recall
const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
const double = (x) => 2 * x;
const isPrime = (n) => ...;
const add = (a, b) => a + b;
const doubled2 = array.map(double);
const primes2 = array.filter(isPrime);
const sum2 = array.reduce(add, 0);
Map operator
Filter operator
Reduce operator
Scan operator
REDUX pattern, ngrx
State…
• State – values of all variables that app has access to
…is projected on…
View…
• View is a function of state 𝑈𝐼 = 𝑓(𝑆𝑡𝑎𝑡𝑒)
…triggers…
Actions…
• Action – object describing what happened.
• Important – action emitting does not modify the state.
…sent to…
Reducer…
• Reducer – pure function, which takes old state and action and gives
the new state
• Important – reducer doesn’t modify the state – creates the new one.
• Important – reducer doesn’t do asynchronous tasks.
…updates…
Store…
• Store – single place which holds state of the application
• Important – State is read-only.
•  database
…contains…
State…
• State – values of all variables that app has access to
…is projected on…
REDUX pattern
Store
State
ViewActions
Reducer
Contains
Is projected on
Triggers
Sent to
Updated
https://medium.com/@flashMasterJim/setting-up-ngrx-store-in-an-angular-2-project-e5232a7b082e#.23yso3phj
Reducer interface
interface ActionReducer<T> {
(state: T, action: Action): T;
}
const dumbReducer = (state, action) => state;
Reducer from example application
export function counterReducer(state: CounterState = initialState,
action?: CounterAction)
: CounterState {
if (!action) {
return state;
}
switch (action.type) {
case CounterActionTypes.START : {
return {...state, main: 0};
}
//...
default: {
return state;
}
}
}
export function counterReducer(state: CounterState = initialState,
action?: CounterAction)
: CounterState {
if (!action) {
return state;
}
switch (action.type) {
case CounterActionTypes.START : {
return {...state, main: 0};
}
//...
default: {
return state;
}
}
}
Reducer from example application
Scan operator – recall
@ngrx/Store
• REDUX inspired
• Based on Observables
• Designed for Angular
Architecture
@ngrx/Store
Service
Smart Comp.
Dumb Comp.
Reducers
new state
select state (observable)
state (observable)
properties (bind)events
call
action (dispatch)
state + action
https://youtu.be/pjwVq8B-ZAw @ 21:55
Architecture
@ngrx/Store
Service
Smart Comp.
Dumb Comp.
Reducers
new state
select state (observable)
state (observable)
properties (bind)events
call
action (dispatch)
state + action
https://youtu.be/pjwVq8B-ZAw @ 21:55
yet another very strong design pattern
@ngrx/Effects
• Very powerful tool to manage side effects
• Based on Observables
• Designed for Angular
• Uses @ngrx/Store
Architecture
@ngrx/Store
Service
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
new state
select state (observable)
state (observable)
properties (bind)events
call
action (dispatch)
state + action
action (dispatch)
state + action
state + action
state (call)
state (call)response (observable)
response (observable)
state + action
https://youtu.be/pjwVq8B-ZAw @ 21:55 & @ 33:45
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.
User action
event
call
dispatch select
state
bindings
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.
database
Inserts
& Updates
Queries
Triggers
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.
• npm install --save-dev @decerto/schematics@latest
• ng g app --collection=@decerto/schematics
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.
@Component({
selector: 'app-counter-view',
template: `
<button (click)="start.emit()">Start</button>
<h2>{{ value }}</h2>
`,
styleUrls: ['app.component.css']
})
export class CounterViewComponent {
@Input() value: number;
@Output() start: EventEmitter<void> = new EventEmitter()
}
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.@Component({
selector: 'app-root',
template: ` <app-counter-view [value]="value$ | async"
(start)="start()"></app-counter-view>`,
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
value$: Observable<number>;
constructor(private cs: CounterService) {
this.value$ = cs.selectMainCounterValue();
}
start() {
this.cs.start();
}
}
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.
@Injectable()
export class CounterService {
constructor(private store: Store<{ counter: CounterState }>) {
}
start() {
this.store.dispatch({type: CounterActionTypes.START});
}
selectMainCounterValue() {
return this.store.select(s => s.counter.main);
}
}
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.export function counterReducer(
state: CounterState = initialState,
action?: CounterAction): CounterState {
if (!action) { return state; }
switch (action.type) {
case CounterActionTypes.START : {
return {...state, main: 0};
}
case CounterActionTypes.TICK : {
return {...state, main: action.value};
}
default: { return state; }
}
}
@Injectable()
export class CounterEffects {
@Effect()
create$ = this.actions$.ofType<CounterStartAction>(
CounterActionTypes.START).pipe(
map(() => this.random.next().value),
map(value => ({type: CounterActionTypes.RANDOM, value})),
);
@Effect()
count$ = this.actions$.ofType<CounterGenerateRandomAction>(
CounterActionTypes.RANDOM).pipe(
mergeMap(({value}) => interval(90).pipe(take(value))),
map((n) => ({type: CounterActionTypes.TICK, value: n + 1})),
);
constructor(private actions$: Actions, private random: XkcdRngService) {
}
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.export function counterReducer(
state: CounterState = initialState,
action?: CounterAction): CounterState {
if (!action) { return state; }
switch (action.type) {
case CounterActionTypes.START : {
return {...state, main: 0};
}
case CounterActionTypes.TICK : {
return {...state, main: action.value};
}
default: { return state; }
}
}
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.
@Injectable()
export class CounterService {
constructor(private store: Store<{ counter: CounterState }>) {
}
start() {
this.store.dispatch({type: CounterActionTypes.START});
}
selectMainCounterValue() {
return this.store.select(s => s.counter.main);
}
}
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.@Component({
selector: 'app-root',
template: ` <app-counter-view [value]="value$ | async"
(start)="start()"></app-counter-view>`,
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
value$: Observable<number>;
constructor(private cs: CounterService) {
this.value$ = cs.selectMainCounterValue();
}
start() {
this.cs.start();
}
}
@Component({
selector: 'app-counter-view',
template: `
<button (click)="start.emit()">Start</button>
<h2>{{ value }}</h2>
`,
styleUrls: ['app.component.css']
})
export class CounterViewComponent {
@Input() value: number;
@Output() start: EventEmitter<void> = new EventEmitter()
}
How to apply in toy project?
step-by-step guide
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.
Demo
https://github.com/pzurowski/toy-project/tree/basic
https://github.com/pzurowski/toy-project/tree/basic-ngrx
Scalable architecture
1. Design API (both http and state)
2. Quick mock data service with static example data
3. Do in parallel:
• Put main logic in actions & reducers
• Put query logic in service
• Put side-effect logic in effects
• Create dumb component
• Create data service
4. Glue everything up
• Smart components bridges services and dumb components
• Dispatch events to store in services
5. Replace mock data service with real one (but you can still use mock in tests)
Scalable architecture
1. Design API (both http and state)
2. Quick mock data service with static example data
3. Do in parallel:
• Put main logic in actions & reducers
• Put query logic in service
• Put side-effect logic in effects
• Create dumb component
• Create data service
4. Glue everything up
• Smart components bridges services and dumb components
• Dispatch events to store in services
5. Replace mock data service with real one (but you can still use mock in tests)
One task can be in progress by 5 developers in one time*
Scalable architecture
1. Design API (both http and state)
2. Quick mock data service with static example data
3. Do in parallel:
• Put main logic in actions & reducers
• Put query logic in service
• Put side-effect logic in effects
• Create dumb component
• Create data service
4. Glue everything up
• Smart components bridges services and dumb components
• Dispatch events to store in services
5. Replace mock data service with real one (but you can still use mock in tests)
One task can be in progress by 5 developers in one time*
*even by 10 with pair programming ;)
Scalable applications
• Think in layers:
• What I want to insert into store
• What I want query from the store (and watch for changes in effective way!)
• What does communicate with other systems (not only backend)
• What I want to show
• Can I divide it into smaller parts
• Do I already have everything in the store
• Has the store normalized state?
Additional benefits of REDUX pattern
• Transactional modification of the application state
• Seperation of View and Logic
• You can persist application state in any moment
• You can restore view from persisted application state
• Time-travel debug – bug reporting made easy
• Dirty checking – you have not to
• You can share some actions with backend
• Easy unit testing
Summary
Declarative, Observable, Redux, Architecture
map-filter-reduce
const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
const double = (x) => 2 * x;
const isPrime = (n) => ...;
const add = (a, b) => a + b;
const doubled2 = array.map(double);
const primes2 = array.filter(isPrime);
const sum2 = array.reduce(add, 0);
Observable - rxMarble
http://reactivex.io/assets/operators/legend.png
REDUX pattern
Store
State
ViewActions
Reducer
Contains
Is projected on
Triggers
Sent to
Updated
https://medium.com/@flashMasterJim/setting-up-ngrx-store-in-an-angular-2-project-e5232a7b082e#.23yso3phj
@ngrx/StoreService
Smart Comp.
Dumb Comp.
Reducers
@ngrx/Effects
Effects Service
Data Service
HTTP
Service
Smart Comp.
Dumb Comp.
User action
event
call
dispatch select
state
bindings
More info
Angular
• paid course by Maximilian Schwarzmüller, ~27 hours
• https://www.udemy.com/the-complete-guide-to-angular-2/
• paid course by Mark Rajcok, ~5 hours
• https://www.udemy.com/angular-2-concepts-code-and-collective-wisdom/
• short book by V. Savkin and J. Cross
• https://gumroad.com/l/essential_angular
rx.js
• paid course by Jafar Husain, ~10 hours
• https://frontendmasters.com/courses/asynchronous-javascript/
• free course by Jafar Husain, ~1 hour
• https://egghead.io/courses/asynchronous-programming-the-end-of-the-loop
• free excercises for both above
• http://reactivex.io/learnrx/
ngrx
• free course by Todd Motto, ~7hours
• https://ultimateangular.com/ngrx-store-effects
Q&A.

More Related Content

What's hot

Exploring Angular 2 - Episode 1
Exploring Angular 2 - Episode 1Exploring Angular 2 - Episode 1
Exploring Angular 2 - Episode 1
Ahmed Moawad
 
JS Fest 2019. Anjana Vakil. Serverless Bebop
JS Fest 2019. Anjana Vakil. Serverless BebopJS Fest 2019. Anjana Vakil. Serverless Bebop
JS Fest 2019. Anjana Vakil. Serverless Bebop
JSFestUA
 
Firebase ng2 zurich
Firebase ng2 zurichFirebase ng2 zurich
Firebase ng2 zurich
Christoffer Noring
 
CodeMash - Building Rich Apps with Groovy SwingBuilder
CodeMash - Building Rich Apps with Groovy SwingBuilderCodeMash - Building Rich Apps with Groovy SwingBuilder
CodeMash - Building Rich Apps with Groovy SwingBuilder
Andres Almiray
 
Angular mix chrisnoring
Angular mix chrisnoringAngular mix chrisnoring
Angular mix chrisnoring
Christoffer Noring
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
Vadym Khondar
 
Kendoui
KendouiKendoui
Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018
Loiane Groner
 
Introduction to Asynchronous scala
Introduction to Asynchronous scalaIntroduction to Asynchronous scala
Introduction to Asynchronous scalaStratio
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
Vincent Pradeilles
 
Scala Future & Promises
Scala Future & PromisesScala Future & Promises
Scala Future & Promises
Knoldus Inc.
 
RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015
Ben Lesh
 
Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4
ICS
 
2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack
Codifly
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
epamspb
 
Functional programming principles
Functional programming principlesFunctional programming principles
Functional programming principles
Andrew Denisov
 
Functional reactive-talk 20170301-001
Functional reactive-talk 20170301-001Functional reactive-talk 20170301-001
Functional reactive-talk 20170301-001
Sven Ruppert
 
Completable future
Completable futureCompletable future
Completable future
Srinivasan Raghvan
 
Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4
ICS
 
Debugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsDebugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template Metaprograms
Platonov Sergey
 

What's hot (20)

Exploring Angular 2 - Episode 1
Exploring Angular 2 - Episode 1Exploring Angular 2 - Episode 1
Exploring Angular 2 - Episode 1
 
JS Fest 2019. Anjana Vakil. Serverless Bebop
JS Fest 2019. Anjana Vakil. Serverless BebopJS Fest 2019. Anjana Vakil. Serverless Bebop
JS Fest 2019. Anjana Vakil. Serverless Bebop
 
Firebase ng2 zurich
Firebase ng2 zurichFirebase ng2 zurich
Firebase ng2 zurich
 
CodeMash - Building Rich Apps with Groovy SwingBuilder
CodeMash - Building Rich Apps with Groovy SwingBuilderCodeMash - Building Rich Apps with Groovy SwingBuilder
CodeMash - Building Rich Apps with Groovy SwingBuilder
 
Angular mix chrisnoring
Angular mix chrisnoringAngular mix chrisnoring
Angular mix chrisnoring
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Kendoui
KendouiKendoui
Kendoui
 
Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018
 
Introduction to Asynchronous scala
Introduction to Asynchronous scalaIntroduction to Asynchronous scala
Introduction to Asynchronous scala
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
 
Scala Future & Promises
Scala Future & PromisesScala Future & Promises
Scala Future & Promises
 
RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015
 
Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4
 
2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
 
Functional programming principles
Functional programming principlesFunctional programming principles
Functional programming principles
 
Functional reactive-talk 20170301-001
Functional reactive-talk 20170301-001Functional reactive-talk 20170301-001
Functional reactive-talk 20170301-001
 
Completable future
Completable futureCompletable future
Completable future
 
Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4
 
Debugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsDebugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template Metaprograms
 

Similar to Architecture for scalable Angular applications (with introduction and extended sample)

Building a TV show with Angular, Bootstrap, and Web Services
Building a TV show with Angular, Bootstrap, and Web ServicesBuilding a TV show with Angular, Bootstrap, and Web Services
Building a TV show with Angular, Bootstrap, and Web Services
David Giard
 
Introduction to Angular2
Introduction to Angular2Introduction to Angular2
Introduction to Angular2
Ivan Matiishyn
 
Angular 2 - The Next Framework
Angular 2 - The Next FrameworkAngular 2 - The Next Framework
Angular 2 - The Next Framework
Commit University
 
Commit University - Exploring Angular 2
Commit University - Exploring Angular 2Commit University - Exploring Angular 2
Commit University - Exploring Angular 2
Commit University
 
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
Sencha
 
Peggy angular 2 in meteor
Peggy   angular 2 in meteorPeggy   angular 2 in meteor
Peggy angular 2 in meteor
LearningTech
 
Jan 2017 - a web of applications (angular 2)
Jan 2017 - a web of applications (angular 2)Jan 2017 - a web of applications (angular 2)
Jan 2017 - a web of applications (angular 2)
Kasper Reijnders
 
Angular 5
Angular 5Angular 5
Lecture2.ppt
Lecture2.pptLecture2.ppt
Lecture2.ppt
TarekHemdan3
 
Angular 16 – the rise of Signals
Angular 16 – the rise of SignalsAngular 16 – the rise of Signals
Angular 16 – the rise of Signals
Coding Academy
 
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
Jeado Ko
 
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점 Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
WebFrameworks
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Fwdays
 
Ngrx
NgrxNgrx
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
Igalia
 
The fundamental problems of GUI applications and why people choose React
The fundamental problems of GUI applications and why people choose ReactThe fundamental problems of GUI applications and why people choose React
The fundamental problems of GUI applications and why people choose React
Oliver N
 
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
Frost
 
はじめてのAngular2
はじめてのAngular2はじめてのAngular2
はじめてのAngular2
Kenichi Kanai
 
Angular 2 - a New Hope
Angular 2 - a New HopeAngular 2 - a New Hope
Angular 2 - a New Hope
Sami Suo-Heikki
 
Angular 2 in-1
Angular 2 in-1 Angular 2 in-1
Angular 2 in-1
GlobalLogic Ukraine
 

Similar to Architecture for scalable Angular applications (with introduction and extended sample) (20)

Building a TV show with Angular, Bootstrap, and Web Services
Building a TV show with Angular, Bootstrap, and Web ServicesBuilding a TV show with Angular, Bootstrap, and Web Services
Building a TV show with Angular, Bootstrap, and Web Services
 
Introduction to Angular2
Introduction to Angular2Introduction to Angular2
Introduction to Angular2
 
Angular 2 - The Next Framework
Angular 2 - The Next FrameworkAngular 2 - The Next Framework
Angular 2 - The Next Framework
 
Commit University - Exploring Angular 2
Commit University - Exploring Angular 2Commit University - Exploring Angular 2
Commit University - Exploring Angular 2
 
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
 
Peggy angular 2 in meteor
Peggy   angular 2 in meteorPeggy   angular 2 in meteor
Peggy angular 2 in meteor
 
Jan 2017 - a web of applications (angular 2)
Jan 2017 - a web of applications (angular 2)Jan 2017 - a web of applications (angular 2)
Jan 2017 - a web of applications (angular 2)
 
Angular 5
Angular 5Angular 5
Angular 5
 
Lecture2.ppt
Lecture2.pptLecture2.ppt
Lecture2.ppt
 
Angular 16 – the rise of Signals
Angular 16 – the rise of SignalsAngular 16 – the rise of Signals
Angular 16 – the rise of Signals
 
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
 
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점 Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
Angular를 활용한 웹 프론트단 개발과 2.0에서 달라진점
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
 
Ngrx
NgrxNgrx
Ngrx
 
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
 
The fundamental problems of GUI applications and why people choose React
The fundamental problems of GUI applications and why people choose ReactThe fundamental problems of GUI applications and why people choose React
The fundamental problems of GUI applications and why people choose React
 
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
 
はじめてのAngular2
はじめてのAngular2はじめてのAngular2
はじめてのAngular2
 
Angular 2 - a New Hope
Angular 2 - a New HopeAngular 2 - a New Hope
Angular 2 - a New Hope
 
Angular 2 in-1
Angular 2 in-1 Angular 2 in-1
Angular 2 in-1
 

Recently uploaded

top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
vrstrong314
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
XfilesPro
 
Why React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdfWhy React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdf
ayushiqss
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
Jelle | Nordend
 
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Hivelance Technology
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
Peter Caitens
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Globus
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Natan Silnitsky
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
Tendenci - The Open Source AMS (Association Management Software)
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
Cyanic lab
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 

Recently uploaded (20)

top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
 
Why React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdfWhy React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdf
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 

Architecture for scalable Angular applications (with introduction and extended sample)

  • 2. Angular Architecture for scalable Angular applications Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
  • 3. Angular Architecture for scalable Angular applications Scalable architecture for Angular applications Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
  • 4. Angular Architecture for scalable Angular applications Scalable architecture for Angular applications with introduction to Angular Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
  • 5. Angular Architecture for scalable Angular applications Scalable architecture for Angular applications with introduction to Angular and more Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
  • 6. Agenda @AboutMe() Angular 2+ Paradigms Promise & array The Pattern Architecture Demo Q&A Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
  • 7. Agenda @AboutMe() Angular 2+ Paradigms Promise & array The Pattern Architecture Demo Q&A Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
  • 8. @AboutMe() • I started programming 19 years ago • I code for money from the 10 years • I code for Decerto ~4 years • I was programming in Pascal, C, PHP, Javascript, Bash, SQL, C++, Java, Typescript • I did some AJAX before it was popular • I did some UX before it was so popular • I did some Devops before it was so named • I was programming SPAs over the last 5 years in AngularJS • I observe the development of Angular 2 since AngularJS 1.5-beta.0 • I am doing SPA in Angular 2–5 from version 2.1.0 Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
  • 9. @AboutMe() • I started programming 19 years ago • I code for money from the 10 years • I code for Decerto ~4 years • I was programming in Pascal, C, PHP, Javascript, Bash, SQL, C++, Java, Typescript • I did some AJAX before it was popular • I did some UX before it was so popular • I did some Devops before it was so named • I was programming SPAs over the last 5 years in AngularJS • I observe the development of Angular 2 since AngularJS 1.5-beta.0 • I am doing SPA in Angular 2–5 from version 2.1.0 Paweł Żurowski <zurowski.pawel@gmail.com> 2018-01-09
  • 10. Angular 2+ crash course How to not write a large or scalable web applications.
  • 11. Toy project • npm install --global @angular/cli@latest # first time only • ng new toy-project # first time only
  • 12. Typescript (open app.component.ts) import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { title = 'app works!'; } ES2015 import modules Exported symbol from module Module in node_modules Decorator (not an annotation!) POJO ES2015 export modules Syntactic sugar for Object with prototypal inharitance String property on instance
  • 13. Toy project – Count to a random number
  • 14. Toy project – Count to a random number AppComponent CounterComponent RandomNumberGeneratorService Plain old button
  • 15. Toy project – Count to a random number • Create counter component • Create Random Number Generator Interface • Define the inferface • Create a RNG Service • Implement counter • Generate random number • Handle click
  • 16. Toy project – create counter component • npm run ng -- generate component --inline-style --inline-template counter
  • 17. Typescript (open counter.component.ts) import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-counter', template: ` <p> counter Works! </p> `, styles: [] }) export class CounterComponent implements OnInit { constructor() { } ngOnInit() { } } Template string Constructor Method Interface
  • 18. Toy project – create interface • npm run ng -- generate interface random-number-generator
  • 19. Typescript (replace random-number-generator.ts) export interface RandomNumberGenerator { readonly name: string; readonly infoUrl: string; next (state: any): {state: any, value: number}; reset (seed?: any): any; } Readonly property… …of type string Return type OptionalMethod signature Value of any type
  • 20. (Simpliest ever random number generator)
  • 21. (Simpliest ever random number generator) https://xkcd.com/221/
  • 22. Toy project – create service • npm run ng -- generate service xkcd-rng
  • 23. import {Injectable} from '@angular/core'; import {RandomNumberGenerator} from './random-number-generator'; @Injectable() export class XkcdRngService implements RandomNumberGenerator { readonly infoUrl = 'https://xkcd.com/221/'; readonly name = 'XKCD Random Number Generator'; reset() { return null; } next(state: any = null) { return {state, value: 4}; } } Typescript (replace xkcd-rng.service.ts) Default value Property shorthand
  • 24. Toy project – implement counter
  • 25. Angular (replace counter.component.ts) import {Component, Input, Output, EventEmitter} from '@angular/core'; @Component({ selector: 'app-counter', template: `{{ tick | async }}`, }) export class CounterComponent { @Input() counter = 5; @Input() delay = 90; @Output() finish = new EventEmitter<boolean>(); @Output() tick = new EventEmitter<number>(); public start(): void { this.count(0); } private count(n: number): void { this.tick.emit(n); if (n >= this.counter) { this.finish.emit(true); } else { setTimeout(() => this.count(n + 1), this.delay); } } } How to not write a large or scalable web applications. It will count to 5 unless you specify otherwise It will be placed in <app-counter> element It will display current tick number whenever it comes It’s a component It will wait 90ms between ticks unless you specify otherwise It will tell you about finish It will tell you about tick You can start counting down Look! There is no $apply!
  • 26. Toy project – generate random number
  • 27. Angular (replace app.component.ts, add XkcdRngService in providers in AppModule) import {Component, OnInit} from '@angular/core'; import {XkcdRngService} from './xkcd-rng.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { counter: number; constructor(public xkcd: XkcdRngService) { } ngOnInit(): void { this.counter = this.xkcd.next().value; } } Dependency injection Assigned to component if public/private specified Lifecycle hook providers: [ XkcdRngService, ],
  • 28. Toy project – handle click
  • 29. Angular (replace app.component.{html,css}) <section> <button (click)="cnt.start()">Start</button> <h2> <app-counter #cnt [counter]="counter"></app-counter> </h2> </section> h2 { display: inline-block; margin: 0; } button { margin: 10px; padding: 10px; } Input in app-counter Property from app-root Handle output Local template variable - definition and usage Access target component API Styles are connected to the component instance, so…
  • 30. Toy project – (quick demo)
  • 32. for vs forEach const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; // for for (let i = 0; i < array.length; ++i) { console.log(array[i]); } // forEach array.forEach((item) => console.log(item));
  • 33. for vs map const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; // for const doubled1 = []; for (let i = 0; i < array.length; ++i) { let double = array[i] * 2; doubled1.push(double); } // map const doubled2 = array.map((item) => 2 * item);
  • 34. for vs filter const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; const isPrime = (n) => ...; // true or false // for const primes1 = []; for (let i = 0; i < array.length; ++i) { if(isPrime(array[i])){ primes1.push(array[i]); } } // filter const primes2 = array.filter(isPrime);
  • 35. for vs reduce const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; // for let sum1 = 0; for (let i = 0; i < array.length; ++i) { sum1 = sum1 + array[i]; } // reduce const sum2 = array.reduce((last, item) => last + item, 0);
  • 36. for vs reduce const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; const add = (a, b) => a + b; // for let sum1 = 0; for (let i = 0; i < array.length; ++i) { sum1 = add(sum1, array[i]); } // reduce const sum2 = array.reduce(add, 0);
  • 37. map-filter-reduce const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; const double = (x) => 2 * x; const isPrime = (n) => ...; const add = (a, b) => a + b; const doubled2 = array.map(double); const primes2 = array.filter(isPrime); const sum2 = array.reduce(add, 0);
  • 38. map-filter-reduce const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; const double = (x) => 2 * x; const isPrime = (n) => ...; const add = (a, b) => a + b; const doubled2 = array.map(double); const primes2 = array.filter(isPrime); const sum2 = array.reduce(add, 0);
  • 39. Primitive value, array, promise, … …
  • 40. Primitive value, array, promise, … number Array <number> Promise <number> ? Single Multiple Now In future
  • 41. Primitive value, array, promise, … number Array <number> Promise <number> ? Single Multiple Now In future
  • 42. Primitive value, array, promise, … number Array <number> Promise <number> ? Single Multiple Now In future
  • 43. Primitive value, array, promise, … number Array <number> Promise <number> Observable <number> Single Multiple Now In future
  • 44. promise vs observable promise .then( (value) => console.log(value)) .catch( (reason) => console.error(reason)) .finally(() => console.log('Done')); observable.subscribe( (value) => console.log(value), (reason) => console.error(reason), () => console.log('Done') );
  • 45. promise vs observable promise .then( (value) => console.log(value)) ; observable.subscribe( (value) => console.log(value) );
  • 46. promise vs observable promise .then((value) => console.log(value)); observable .subscribe((value) => console.log(value));
  • 47. promise vs observable promise .then((value) => console.log(value)); observable .subscribe((value) => console.log(value));
  • 48. Primitive value, array, promise, observable number Iterable <number> Promise <number> Observable <number> pull semantics push semantics Single Multiple Now In future
  • 55. RxJS operators audit, auditTime, buffer, bufferCount, bufferTime, bufferToggle, bufferWhen, catchError, combineAll, combineLatest, concat, concatAll, concatMap, concatMapTo, count, debounce, debounceTime, defaultIfEmpty, delay, delayWhen, dematerialize, distinct, distinctUntilChanged, distinctUntilKeyChanged, elementAt, every, exhaust, exhaustMap, expand, filter, finalize, find, findIndex, first, groupBy, ignoreElements, isEmpty, last, map, mapTo, materialize, max, merge, mergeAll, mergeMap, flatMap, mergeMapTo, mergeScan, min, multicast, observeOn, onErrorResumeNext, pairwise, partition, pluck, publish, publishBehavior, publishLast, publishReplay, race, reduce, repeat, repeatWhen, retry, retryWhen, refCount, sample, sampleTime, scan, sequenceEqual, share, shareReplay, single, skip, skipLast, skipUntil, skipWhile, startWith, switchAll, switchMap, switchMapTo, take, takeLast, takeUntil, takeWhile, tap, throttle, throttleTime, timeInterval, timeout, timeoutWith, timestamp, toArray, window, windowCount, windowTime, windowToggle, windowWhen, withLatestFrom, zip, zipAll
  • 56. map-filter-reduce --- recall const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; const double = (x) => 2 * x; const isPrime = (n) => ...; const add = (a, b) => a + b; const doubled2 = array.map(double); const primes2 = array.filter(isPrime); const sum2 = array.reduce(add, 0);
  • 62. State… • State – values of all variables that app has access to …is projected on…
  • 63. View… • View is a function of state 𝑈𝐼 = 𝑓(𝑆𝑡𝑎𝑡𝑒) …triggers…
  • 64. Actions… • Action – object describing what happened. • Important – action emitting does not modify the state. …sent to…
  • 65. Reducer… • Reducer – pure function, which takes old state and action and gives the new state • Important – reducer doesn’t modify the state – creates the new one. • Important – reducer doesn’t do asynchronous tasks. …updates…
  • 66. Store… • Store – single place which holds state of the application • Important – State is read-only. •  database …contains…
  • 67. State… • State – values of all variables that app has access to …is projected on…
  • 68. REDUX pattern Store State ViewActions Reducer Contains Is projected on Triggers Sent to Updated https://medium.com/@flashMasterJim/setting-up-ngrx-store-in-an-angular-2-project-e5232a7b082e#.23yso3phj
  • 69. Reducer interface interface ActionReducer<T> { (state: T, action: Action): T; } const dumbReducer = (state, action) => state;
  • 70. Reducer from example application export function counterReducer(state: CounterState = initialState, action?: CounterAction) : CounterState { if (!action) { return state; } switch (action.type) { case CounterActionTypes.START : { return {...state, main: 0}; } //... default: { return state; } } }
  • 71. export function counterReducer(state: CounterState = initialState, action?: CounterAction) : CounterState { if (!action) { return state; } switch (action.type) { case CounterActionTypes.START : { return {...state, main: 0}; } //... default: { return state; } } } Reducer from example application
  • 73. @ngrx/Store • REDUX inspired • Based on Observables • Designed for Angular
  • 74. Architecture @ngrx/Store Service Smart Comp. Dumb Comp. Reducers new state select state (observable) state (observable) properties (bind)events call action (dispatch) state + action https://youtu.be/pjwVq8B-ZAw @ 21:55
  • 75. Architecture @ngrx/Store Service Smart Comp. Dumb Comp. Reducers new state select state (observable) state (observable) properties (bind)events call action (dispatch) state + action https://youtu.be/pjwVq8B-ZAw @ 21:55 yet another very strong design pattern
  • 76. @ngrx/Effects • Very powerful tool to manage side effects • Based on Observables • Designed for Angular • Uses @ngrx/Store
  • 77. Architecture @ngrx/Store Service Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP new state select state (observable) state (observable) properties (bind)events call action (dispatch) state + action action (dispatch) state + action state + action state (call) state (call)response (observable) response (observable) state + action https://youtu.be/pjwVq8B-ZAw @ 21:55 & @ 33:45
  • 78. @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp. User action event call dispatch select state bindings
  • 79. @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp. database Inserts & Updates Queries Triggers
  • 80. How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp.
  • 81. How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp. • npm install --save-dev @decerto/schematics@latest • ng g app --collection=@decerto/schematics
  • 82. How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp. @Component({ selector: 'app-counter-view', template: ` <button (click)="start.emit()">Start</button> <h2>{{ value }}</h2> `, styleUrls: ['app.component.css'] }) export class CounterViewComponent { @Input() value: number; @Output() start: EventEmitter<void> = new EventEmitter() }
  • 83. How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp.@Component({ selector: 'app-root', template: ` <app-counter-view [value]="value$ | async" (start)="start()"></app-counter-view>`, styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { value$: Observable<number>; constructor(private cs: CounterService) { this.value$ = cs.selectMainCounterValue(); } start() { this.cs.start(); } }
  • 84. How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp. @Injectable() export class CounterService { constructor(private store: Store<{ counter: CounterState }>) { } start() { this.store.dispatch({type: CounterActionTypes.START}); } selectMainCounterValue() { return this.store.select(s => s.counter.main); } }
  • 85. How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp.export function counterReducer( state: CounterState = initialState, action?: CounterAction): CounterState { if (!action) { return state; } switch (action.type) { case CounterActionTypes.START : { return {...state, main: 0}; } case CounterActionTypes.TICK : { return {...state, main: action.value}; } default: { return state; } } }
  • 86. @Injectable() export class CounterEffects { @Effect() create$ = this.actions$.ofType<CounterStartAction>( CounterActionTypes.START).pipe( map(() => this.random.next().value), map(value => ({type: CounterActionTypes.RANDOM, value})), ); @Effect() count$ = this.actions$.ofType<CounterGenerateRandomAction>( CounterActionTypes.RANDOM).pipe( mergeMap(({value}) => interval(90).pipe(take(value))), map((n) => ({type: CounterActionTypes.TICK, value: n + 1})), ); constructor(private actions$: Actions, private random: XkcdRngService) { } How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp.
  • 87. How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp.export function counterReducer( state: CounterState = initialState, action?: CounterAction): CounterState { if (!action) { return state; } switch (action.type) { case CounterActionTypes.START : { return {...state, main: 0}; } case CounterActionTypes.TICK : { return {...state, main: action.value}; } default: { return state; } } }
  • 88. How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp. @Injectable() export class CounterService { constructor(private store: Store<{ counter: CounterState }>) { } start() { this.store.dispatch({type: CounterActionTypes.START}); } selectMainCounterValue() { return this.store.select(s => s.counter.main); } }
  • 89. How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp.@Component({ selector: 'app-root', template: ` <app-counter-view [value]="value$ | async" (start)="start()"></app-counter-view>`, styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { value$: Observable<number>; constructor(private cs: CounterService) { this.value$ = cs.selectMainCounterValue(); } start() { this.cs.start(); } }
  • 90. @Component({ selector: 'app-counter-view', template: ` <button (click)="start.emit()">Start</button> <h2>{{ value }}</h2> `, styleUrls: ['app.component.css'] }) export class CounterViewComponent { @Input() value: number; @Output() start: EventEmitter<void> = new EventEmitter() } How to apply in toy project? step-by-step guide @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp.
  • 92.
  • 93. Scalable architecture 1. Design API (both http and state) 2. Quick mock data service with static example data 3. Do in parallel: • Put main logic in actions & reducers • Put query logic in service • Put side-effect logic in effects • Create dumb component • Create data service 4. Glue everything up • Smart components bridges services and dumb components • Dispatch events to store in services 5. Replace mock data service with real one (but you can still use mock in tests)
  • 94. Scalable architecture 1. Design API (both http and state) 2. Quick mock data service with static example data 3. Do in parallel: • Put main logic in actions & reducers • Put query logic in service • Put side-effect logic in effects • Create dumb component • Create data service 4. Glue everything up • Smart components bridges services and dumb components • Dispatch events to store in services 5. Replace mock data service with real one (but you can still use mock in tests) One task can be in progress by 5 developers in one time*
  • 95. Scalable architecture 1. Design API (both http and state) 2. Quick mock data service with static example data 3. Do in parallel: • Put main logic in actions & reducers • Put query logic in service • Put side-effect logic in effects • Create dumb component • Create data service 4. Glue everything up • Smart components bridges services and dumb components • Dispatch events to store in services 5. Replace mock data service with real one (but you can still use mock in tests) One task can be in progress by 5 developers in one time* *even by 10 with pair programming ;)
  • 96. Scalable applications • Think in layers: • What I want to insert into store • What I want query from the store (and watch for changes in effective way!) • What does communicate with other systems (not only backend) • What I want to show • Can I divide it into smaller parts • Do I already have everything in the store • Has the store normalized state?
  • 97. Additional benefits of REDUX pattern • Transactional modification of the application state • Seperation of View and Logic • You can persist application state in any moment • You can restore view from persisted application state • Time-travel debug – bug reporting made easy • Dirty checking – you have not to • You can share some actions with backend • Easy unit testing
  • 99. map-filter-reduce const array = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; const double = (x) => 2 * x; const isPrime = (n) => ...; const add = (a, b) => a + b; const doubled2 = array.map(double); const primes2 = array.filter(isPrime); const sum2 = array.reduce(add, 0);
  • 101. REDUX pattern Store State ViewActions Reducer Contains Is projected on Triggers Sent to Updated https://medium.com/@flashMasterJim/setting-up-ngrx-store-in-an-angular-2-project-e5232a7b082e#.23yso3phj
  • 102. @ngrx/StoreService Smart Comp. Dumb Comp. Reducers @ngrx/Effects Effects Service Data Service HTTP Service Smart Comp. Dumb Comp. User action event call dispatch select state bindings
  • 103. More info Angular • paid course by Maximilian Schwarzmüller, ~27 hours • https://www.udemy.com/the-complete-guide-to-angular-2/ • paid course by Mark Rajcok, ~5 hours • https://www.udemy.com/angular-2-concepts-code-and-collective-wisdom/ • short book by V. Savkin and J. Cross • https://gumroad.com/l/essential_angular rx.js • paid course by Jafar Husain, ~10 hours • https://frontendmasters.com/courses/asynchronous-javascript/ • free course by Jafar Husain, ~1 hour • https://egghead.io/courses/asynchronous-programming-the-end-of-the-loop • free excercises for both above • http://reactivex.io/learnrx/ ngrx • free course by Todd Motto, ~7hours • https://ultimateangular.com/ngrx-store-effects
  • 104. Q&A.