SlideShare una empresa de Scribd logo
1 de 65
How SPAs got their groove back
Christoffer Noring
Google Developer Expert
@chris_noring
© AngularMIX All rights reserved.
https://www.angularmix.com
Speaker: Christoffer Noring
 Google Developer Expert
 Telerik Developer Expert ( NativeScript )
 Fullstack Developer at Digital McKinsey
 London Javascript meetup Organizer
 Author of RxJS Ultimate
© AngularMIX All rights reserved.
https://www.angularmix.com
Introduction
 Overview
 The lost groove
 Async and Callback Hell
 The limitations of Promises
 Introducing the App fu
 RxJS beginner to master
 Everything is not Response/ Request
 Web Sockets, Socket.io
 E.g Updated feeds and polling, Earthquake API, Firebase
 All together now – The Feed pattern
We all need a Rob in a our lives
© AngularMIX All rights reserved.
https://www.angularmix.com
Why should I care?
Remember, we write code for humans
Knowing RxJS and how to use it Angular will:
Make you write less code
Make less mistakes that leads to memory leaks
Make you write simpler code that is easier to maintain
© AngularMIX All rights reserved.
https://www.angularmix.com
We’ve lost our direction ( groove )
 Dealing with async code is painful
 Our paradigm is usually how over what = we write too much code
© AngularMIX All rights reserved.
https://www.angularmix.com
Async history
callback hell
getData('url', data => {
getMoreData('url2/'+ data.id, (moreData) => {
getEvenMoreData('url3' + moreData.id, (evenMoreData) => {
/* do something*/
});
});
});
Pain, so much pain
© AngularMIX All rights reserved.
https://www.angularmix.com
Async history
enter Promises
getData()
.then( getMoreData )
.then( getEvenMoreData )
.catch( handleError );
Now we are talking, readable async
© AngularMIX All rights reserved.
https://www.angularmix.com
Async present day
async/await
async function get () {
let data = await getData('url');
let moreData = await getMoreData('url2' + data.id);
let evenMore = await getEvenMore('url3',moreData.id);
return evenMore;
}
get().then( data => console.log( 'data', data ));
Everything is great or?
© AngularMIX All rights reserved.
https://www.angularmix.com
Promises are limited
what to use for complex scenarios?
 Returns one value
 Hard to retry
 No cancellation
 Doesn’t mix easily with other async concepts
© AngularMIX All rights reserved.
https://www.angularmix.com
There is a better to way to do async
and its part of Angular – RxJS
from Daniel La Russo to Miyagi
© AngularMIX All rights reserved.
https://www.angularmix.com
1 2 3
Time
Observable – stream of data over time
© AngularMIX All rights reserved.
https://www.angularmix.com
Observables
let stream$ = Observable.create( observer => {
observer.next( 1 );
});
stream$.subscribe(
data => console.log('data', data)
);
Generate value here
Subscribe here
© AngularMIX All rights reserved.
https://www.angularmix.com
Observables + error
let stream$ = Observable.create( observer => {
observer.next( 1 );
observer.error('err');
});
stream$.subscribe(
data => console.log('data', data),
err => console.error('err', err) // err
);
Error produced
Subscribe to error here
© AngularMIX All rights reserved.
https://www.angularmix.com
Observables - completion
let stream$ = Observable.create( observer => {
observer.next( 1 );
observer.complete();
});
stream$.subscribe(
data => console.log('data', data),
err => console.error('err', err),
() => console.log('complete')
);
Complete the stream
Subscribe to complete
No more value will be generated
© AngularMIX All rights reserved.
https://www.angularmix.com
let stream$ = Observable.create( observer => {
let counter = 0;
let id = setInterval(() => observer.next(counter++), 1000);
return function(){ clearInterval(id); }
});
let subscription = stream$.subscribe(
data => console.log(‘data’, data)
);
setTimeout(() => subscription.unsubscribe());
Cancelling aka unsubscribing
Cleaning up resources
Define a clean up method
© AngularMIX All rights reserved.
https://www.angularmix.com
But mostly because Kobra Kai says we can’t
Knowledge is understanding how to build it,
So let’s build our own RxJS
© AngularMIX All rights reserved.
https://www.angularmix.com
 create() operator
 subscribe()
 unsubscribe()
 adding a filter() operator
What to build
© AngularMIX All rights reserved.
https://www.angularmix.com
We should have a behaviour function
that takes an observer as a parameter
We should have a create method
on our Observable class
We should have an Observable class
let stream$ = Observable.create( observer => {
observer.next( 1 );
});
Create a stream
© AngularMIX All rights reserved.
https://www.angularmix.com
create() needs to return an Observable instance and
save the behaviour function
class Observable {
constructor( behaviourFn ) { this.behaviourFn = behaviourFn; }
create( behaviourFn ) { return new Observable(behaviourFn); }
}
Observer class
© AngularMIX All rights reserved.
https://www.angularmix.com
Data callback
We need to define an Observer class
class Observable {
constructor( behaviourFn ) { this.behaviourFn = behaviourFn; }
create(behaviourFn) { return new Observable(behaviourFn); }
subscribe( dataFn ) {
behaviourFn( observer );
}
}
stream$.subscribe( data => console.log(data));
And this guy, dataFn
needs to go somewhere
Subscribe to the stream
© AngularMIX All rights reserved.
https://www.angularmix.com
class Observer {
constructor( dataFn ) { this.dataFn = dataFn; }
next(val) { this.dataFn( val ); }
}
When we call next(),
we need to call dataFn()
Observer class
© AngularMIX All rights reserved.
https://www.angularmix.com
class Observable {
constructor( behaviourFn ) { this.behaviourFn = behaviourFn; }
create(behaviourFn) { return new Observable(behaviourFn); }
subscribe( dataFn ) {
let observer = new Observer( dataFn );
behaviourFn( observer );
}
}
provide dataFn() to Observer so it may be used when calling
.next()
Update Observable class
© AngularMIX All rights reserved.
https://www.angularmix.com
let stream$ = Observable.create( observer => {
observer.next(1);
observer.next(2);
});
stream$.subscribe( data => console.log(‘sub1’, data));
// Sub1 1, Sub1 2
stream$.subscribe( data => console.log(‘sub2’, data));
// Sub2 1,Sub 2 2
It works!!
Put it to the test
© AngularMIX All rights reserved.
https://www.angularmix.com
We are one with the stream
© AngularMIX All rights reserved.
https://www.angularmix.com
let stream$ = Observable.create( observer => {
let counter = 0;
let id = setInterval(() => {
observer.next(counter++);
}, 1000);
return function() { clearInterval(id); }
});
Let’s create something
worth unsubscribing to
Let’s define a clean up
method
Add unsubscribe
© AngularMIX All rights reserved.
https://www.angularmix.com
class Observable {
constructor( behaviourFn ) { this.behaviourFn = behaviourFn; }
create(behaviourFn) { return new Observable(behaviourFn); }
subscribe( dataFn ) {
let observer = new Observer( dataFn );
let cleanUpFn = behaviorFn( observer );
return {
unsubscribe : cleanUpFn
};
}
}
behaviourFn IS our clean up function,
just return it from the unsubscribe() method
Let’s update Observable class
© AngularMIX All rights reserved.
https://www.angularmix.com
let stream$ = Observable.create( observer => {
let counter = 0;
let id = setInterval(() => {
observer.next(counter++);
}, 1000);
return function() { clearInterval(id); }
});
stream$.unsubscribe();
This is called
When we call this
And using it
© AngularMIX All rights reserved.
https://www.angularmix.com
Cleanup successful
© AngularMIX All rights reserved.
https://www.angularmix.com
Summary so far
 Observables
 Observer
 Unsubscribe
We know how to build
© AngularMIX All rights reserved.
https://www.angularmix.com
Wisdom is to NOT build it, because other people do
it better
And there is a GitHub project already,
so contribute
© AngularMIX All rights reserved.
https://www.angularmix.com
Operators
The thing that empowers Observables
© AngularMIX All rights reserved.
https://www.angularmix.com
Operators
Operators can:
- Operate on your data
- Decide the speed of the stream
- Combine streams
- Change streams
And much more
let stream$ = Rx.Observable
.of(1, 2, 3);
.operator()
.operator()
.operator();
Define your stream
Apply operator after operator
© AngularMIX All rights reserved.
https://www.angularmix.com
Operators- categories
Construction Conversion Combination
Mathematical Time Grouping
© AngularMIX All rights reserved.
https://www.angularmix.com
There is an operator for everything
let stream$ = Rx.Observable
.of(1,2,3)
.map( )
.filter()
.toPromise()
.then(
data => console.log(data)
)
Don’t make bunny sad though
Even for converting Observable to
Promise
© AngularMIX All rights reserved.
https://www.angularmix.com
Operators- build it yourself
© AngularMIX All rights reserved.
https://www.angularmix.com
class Observable {
constructor( behaviour ) {
this.behaviour = behaviour;
}
filter(fnFilter) {
let obs = new FilterableObservable(this.behaviour, fnFilter);
return obs;
}
static create( behaviour ) {
return new Observable( behaviour );
}
subscribe( fnData ) {
let observer = new Observer(fnData);
this.behaviour( observer );
}
}
Add filter() – update our Observable class
We need a new
type of Observable
We send in behaviour
and filter function
© AngularMIX All rights reserved.
https://www.angularmix.com
class FilterableObservable extends Observable {
constructor(behaviour, filter) {
super(behaviour);
this.filter = filter;
}
subscribe(fnData) {
let observer = new Observer( fnData );
observer.next = (val) => {
if(this.filter(val)){ fnData( val ); }
};
this.behaviour( observer );
}
}
FilterableObservable
For every value, check
with our filter() if it should
be emitted
We even know how to build
Operators now
© AngularMIX All rights reserved.
https://www.angularmix.com
Before talking about Angular with RxJS
Wrap Observable
Change from
one stream to the next
Let’s learn a couple of more concepts
© AngularMIX All rights reserved.
https://www.angularmix.com
let stream$ = Rx.Observable.create(observer => {
someAsyncFunction((val) => {
observer.next( val );
observer.complete();
});
});
stream$.subscribe( data => {
console.log('async data', data);
});
Wrapping, fulfill the contract
function someAsyncFunction(cb){
setTimeout(() => { cb('some value'); },3000);
}
Allows us to make anything async
part of Observables and RxJS
A callback function turned into an Observable
© AngularMIX All rights reserved.
https://www.angularmix.com
let elem = document.getElementById('text');
let stream = Rx.Observable
.fromEvent(elem,'keyup')
.switchMap( data => {
return new Rx.Observable.of('some data back based on: '+ data);
});
stream.subscribe( data => {
console.log('data', data);
})
Change from one type of stream to the next
flatMap(), switchMap()
keyUp stream
Change into new stream
© AngularMIX All rights reserved.
https://www.angularmix.com
Working with switchMap/flatMap is a key concept
You are able to divide up your code into multiple stream,
Aka you are able to break down the problem
keykey key
AJAX AJAX AJAX
Combine different types of streams
to build your algorithm
It will also make it easier to isolate errors into
a specific stream
© AngularMIX All rights reserved.
https://www.angularmix.com
Angular comes with RxJS in everything
© AngularMIX All rights reserved.
https://www.angularmix.com
Angular comes with RxJS
an async scenario that grows with you
class Service{
constructor(private http:HttpClient) {}
getData() {
return this.httpClient
.get('url')
.map( this.mapPeople );
}
mapPeople():Array<Person> {
return json => json.map( person => new Person(person));
}
}
Get your HTTP data with HttpClien
© AngularMIX All rights reserved.
https://www.angularmix.com
export class PeopleComponent
implements OnInit,
implements OnDestroy {
people:Array<Person>;
subscription;
constructor(private srv: Service) {}
ngOnInit() {
this.subscription = srv.getData()
.subscribe( data => this.people = data );
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Subscribe
Call unsubscribe on destroying
component
Angular WITHOUT async pipe
© AngularMIX All rights reserved.
https://www.angularmix.com
Angular removes Cancelling
with async pipe@Component({
template : `
<div *ngFor="let person of people$ | async">
{{ person.name }}
</div>
`
})
export class PeopleComponent implements OnInit {
people$:Observable<Person>;
constructor(private srv: Service) {}
ngOnInit() { this.people$ = srv.getData(); }
}
No more
subscribe()
Or
Unsubscribe()
© AngularMIX All rights reserved.
https://www.angularmix.com
class Service{
people: Array<Person>;
constructor(private http:HttpClient) {}
getData() {
return this.httpClient
.get('url')
.map( this.mapPeople )
.do( data => localStorage.setItem(‘people’,data); )
.catch( err => {
let people = localStorage.getItem(‘people’);
return of(people !== null ? people : []);
})
}
}
Handle offline
with localStorage
Save response to cac
Retrieve cached response
if erroring out
© AngularMIX All rights reserved.
https://www.angularmix.com
class Service{
constructor(private http:HttpClient) {}
getData() {
return this.httpClient
.get('url')
.map( this.mapPeople )
.retryWhen( err => err.delay(200) )
.take(noOfAttemptsBeforeGivingUp)
}
}
Handle shaky connections
with retryWhen
Delays each attempt with 200ms,
Also retries x times
Ok to do, but stream finishes,
after x attempts
© AngularMIX All rights reserved.
https://www.angularmix.com
class Service{
constructor(private http:HttpClient) {}
getData() {
return this.httpClient
.get('url')
.map( this.mapPeople )
.retryWhen( err => {
err
.scan((errCount, err) =>
if(errCount === 2) { throw ‘giving up’ }
else { return errCount + 1; }
,0)
.delay(200 * errCount) // progressive increase
time
})
.take(noOfAttemptsBeforeGivingUp) // 404,500
}
}
Handle shaky connections
better solution
stream$.subscribe(
data => console.log(
'err stream',
data
),
err => console.log(
'erroring out after x retries',
respondWithCachedData)
)
errorCount, delay and termination
Sort out why it failed to see
wether it is worth retrying
© AngularMIX All rights reserved.
https://www.angularmix.com
From a service to a feed
What is a feed?
Why do we want a feed?
There might be more than one component wanting to consume the data
We don’t want to do unnecessary HTTP calls
An exposed Observable that can have many subscribers
© AngularMIX All rights reserved.
https://www.angularmix.com
From a service to a feed
class Service{
people: Array<Person>;
constructor(private http:HttpClient) {
this.fetchData();
}
fetchData() {
return this.httpClient
.get('url')
.map( this.mapPeople )
.subscribe( data => this.people = data );
}
} @Component({})
export class PeopleComponent implements OnInit
{
private people: Array<Person>;
constructor(private srv: PersonService) { }
get people() { return this.srv.people; }
}
We can do this with a minimum of RxJS,
Trust in Angulars change detection
Use this for Change Detection
to trigger
© AngularMIX All rights reserved.
https://www.angularmix.com
What did we learn on services?
We should handle offline
We should handle shaky connections
How to build a feed service
© AngularMIX All rights reserved.
https://www.angularmix.com
There is more than HTTP
 HTTP
 Web Sockets, Full Duplex connections
 Firebase
 Socket.io
 HTTP + Polling feeds
And it affects how we write our
service and consumes it
© AngularMIX All rights reserved.
https://www.angularmix.com
Building our service
add Socket.io
import * as io from 'socket.io-client';
export class TaskService {
subscription;
tasks:Task[] = [];
constructor(private http:Http) {
this.fetchData();
this.socket = io(this.url);
this.socket.on('task', (data) => {
this.tasks = [ ...this.tasks, data ];
});
}
private fetchData() { /* omitted */ }
}
We can use our feed pattern,
but what if we want to
listen to changes?
And display CSS
© AngularMIX All rights reserved.
https://www.angularmix.com
Two different approaches
we want to know when a change happens
One of the few cases when a Subject might be need
.share()
.replay(1)
BehaviourSubject
© AngularMIX All rights reserved.
https://www.angularmix.com
Adding BehaviourSubject
export class TaskService {
private internalStore:BehaviourSubject;
constructor() { this.internalStore = new BehaviourSubject([]); }
get store() { return this.internalStore.asObservable(); }
private fetchTasks(){
this.http
.get('/data/tasks.json')
.map(response => response.json())
.map(this.mapTasks)
.do( data => {
this._store.next( data );
localStorage.setItem('tasks', JSON.stringify(data))
})
.catch( err => {
return Rx.Observable.of(this.fetchLocalStorage());
});
}
}
Initialize Subject
Expose as Observable, aka
defensive coding
Gives us start data,
also remembers last emitted
© AngularMIX All rights reserved.
https://www.angularmix.com
Building our service
consuming our service
@Component({})
export class TaskComponent implements OnInit {
constructor(private srv: TaskService) {}
ngOnInit() {
this.srv.store.subscribe( tasks => {
// tasks where updated somehow, show CSS
});
}
}
Only when we care about changes,
REMEMBER most of the time we don’t need a Subject
© AngularMIX All rights reserved.
https://www.angularmix.com
Earthquake API
HTTP Polling
 The title (28 pt) uses the dark red (the 4th color in the template)
 The subtitle is 1 size smaller (24 pt) and should always uses the theme
gray color (2nd color in the template)
 Text here is 20 pt
 18 pt
 16 pt
© AngularMIX All rights reserved.
https://www.angularmix.com
Mixing different async concepts
Rich composition
Naive Little better Angular version
© AngularMIX All rights reserved.
https://www.angularmix.com
First naive approach
let elem = document.getElementById('text');
let stream = Rx.Observable
.fromEvent(elem,'keyup')
.map( ev => ev.key )
.filter( key => {
return elem.value.length > 3;
})
.switchMap( data => {
return new Rx.Observable.of('some data back based on: '+ data);
});
Only do something when
We have enough entered charac
From keystream to AJAX stream, playing nice with
other async concepts – rich composition
© AngularMIX All rights reserved.
https://www.angularmix.com
Better approach
let elem = document.getElementById('text');
let stream = Rx.Observable
.fromEvent(elem,'keyup')
.map( ev => ev.key )
.debounceTime(500)
.switchMap( data => {
return new Rx.Observable.of('some data back
based on: '+ data);
});
Wait til the user stopped
typing for 500ms
© AngularMIX All rights reserved.
https://www.angularmix.com
Angular approach - service
export class ServiceService {
constructor(private http: HttpClient) {}
httpSearch(inputText: string) {
return this.http.get('url?query=${inputText}');
}
}
A simple http.get() call
© AngularMIX All rights reserved.
https://www.angularmix.com
Angular approach - component
<input type="text" [formControl] = "input" class="form-control” />
<div *ngFor="let term in result | async">
{{term}}
</div>
@Component({})
export class SearchComponent {
result$:Observable;
input = new FormControl();
constructor(private srv:SearchService) {
this.result$ = this.input
.valueChanges
.debounceTime(500)
.distinctUntilChanged()
.switchMap(inputText => this.srv.httpSearch(inputText))
}
}
Capture change,
when it happens
© AngularMIX All rights reserved.
https://www.angularmix.com
Summary
 We actually understand how to build RxJS
 Angular helps out with async pipe and its own change detection
 RxJS does a lot of the heavy lifting thanks to
 Operators for manipulating data
 Operators for advanced error scenarios such as retry etc..
 Some constructs in RxJS should be sparsely used like Subject
 We can rich composition, cause everything async can be made into
an Observable
© AngularMIX All rights reserved.
https://www.angularmix.com
My free gitbook on RxJS
 angular.io/resources RxJS 5 Ultimate
 Help me make it better or just tell your friends
 Power to the community
© AngularMIX All rights reserved.
https://www.angularmix.com
Thank you
promise
.retry(4)
.kungfuKid(1)
@chris_noring

Más contenido relacionado

La actualidad más candente

[AngularJS] From Angular to Mobile in 30 minutes
[AngularJS] From Angular to Mobile in 30 minutes[AngularJS] From Angular to Mobile in 30 minutes
[AngularJS] From Angular to Mobile in 30 minutesGlobant
 
Redux Sagas - React Alicante
Redux Sagas - React AlicanteRedux Sagas - React Alicante
Redux Sagas - React AlicanteIgnacio Martín
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Astrails
 
Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6Ignacio Martín
 
Protocol-Oriented Networking
Protocol-Oriented NetworkingProtocol-Oriented Networking
Protocol-Oriented NetworkingMostafa Amer
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with JasmineTim Tyrrell
 
Introduction to ReactJS and Redux
Introduction to ReactJS and ReduxIntroduction to ReactJS and Redux
Introduction to ReactJS and ReduxBoris Dinkevich
 
The Ring programming language version 1.3 book - Part 30 of 88
The Ring programming language version 1.3 book - Part 30 of 88The Ring programming language version 1.3 book - Part 30 of 88
The Ring programming language version 1.3 book - Part 30 of 88Mahmoud Samir Fayed
 
Javascript Promises/Q Library
Javascript Promises/Q LibraryJavascript Promises/Q Library
Javascript Promises/Q Libraryasync_io
 
Why Redux-Observable?
Why Redux-Observable?Why Redux-Observable?
Why Redux-Observable?Anna Su
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineRaimonds Simanovskis
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sMy Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sRoel Hartman
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAnkit Agarwal
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptŁukasz Kużyński
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsPiotr Pelczar
 

La actualidad más candente (20)

Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
[AngularJS] From Angular to Mobile in 30 minutes
[AngularJS] From Angular to Mobile in 30 minutes[AngularJS] From Angular to Mobile in 30 minutes
[AngularJS] From Angular to Mobile in 30 minutes
 
Redux Sagas - React Alicante
Redux Sagas - React AlicanteRedux Sagas - React Alicante
Redux Sagas - React Alicante
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
 
Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6
 
Protocol-Oriented Networking
Protocol-Oriented NetworkingProtocol-Oriented Networking
Protocol-Oriented Networking
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with Jasmine
 
Introduction to ReactJS and Redux
Introduction to ReactJS and ReduxIntroduction to ReactJS and Redux
Introduction to ReactJS and Redux
 
Testing AngularJS
Testing AngularJSTesting AngularJS
Testing AngularJS
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
The Ring programming language version 1.3 book - Part 30 of 88
The Ring programming language version 1.3 book - Part 30 of 88The Ring programming language version 1.3 book - Part 30 of 88
The Ring programming language version 1.3 book - Part 30 of 88
 
Javascript Promises/Q Library
Javascript Promises/Q LibraryJavascript Promises/Q Library
Javascript Promises/Q Library
 
Why Redux-Observable?
Why Redux-Observable?Why Redux-Observable?
Why Redux-Observable?
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sMy Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promises
 
Gwt and Xtend
Gwt and XtendGwt and Xtend
Gwt and Xtend
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascript
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 

Similar a Angular mix chrisnoring

Reactive application using meteor
Reactive application using meteorReactive application using meteor
Reactive application using meteorSapna Upreti
 
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 2018Loiane Groner
 
Reactive Application Using METEOR
Reactive Application Using METEORReactive Application Using METEOR
Reactive Application Using METEORNodeXperts
 
apidays Australia 2022 - Spinning Your Drones with Cadence Workflows and Apac...
apidays Australia 2022 - Spinning Your Drones with Cadence Workflows and Apac...apidays Australia 2022 - Spinning Your Drones with Cadence Workflows and Apac...
apidays Australia 2022 - Spinning Your Drones with Cadence Workflows and Apac...apidays
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in reactBOSC Tech Labs
 
Universal JS Applications with React
Universal JS Applications with ReactUniversal JS Applications with React
Universal JS Applications with ReactThanh Trần Trọng
 
TPSE Thailand 2015 - Rethinking Web with React and Flux
TPSE Thailand 2015 - Rethinking Web with React and FluxTPSE Thailand 2015 - Rethinking Web with React and Flux
TPSE Thailand 2015 - Rethinking Web with React and FluxJirat Kijlerdpornpailoj
 
Ring: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic ClojureRing: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic ClojureMark McGranaghan
 
Running Serverless at The Edge (CTD302) - AWS re:Invent 2018
Running Serverless at The Edge (CTD302) - AWS re:Invent 2018Running Serverless at The Edge (CTD302) - AWS re:Invent 2018
Running Serverless at The Edge (CTD302) - AWS re:Invent 2018Amazon Web Services
 
Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Matt Raible
 
Spinning your Drones with Cadence Workflows and Apache Kafka
Spinning your Drones with Cadence Workflows and Apache KafkaSpinning your Drones with Cadence Workflows and Apache Kafka
Spinning your Drones with Cadence Workflows and Apache KafkaPaul Brebner
 
Traffic Management In The Cloud
Traffic Management In The CloudTraffic Management In The Cloud
Traffic Management In The CloudIntel Corporation
 
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and ScalaWriting highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and Scalajfarcand
 
AngularJS Basics
AngularJS BasicsAngularJS Basics
AngularJS BasicsRavi Mone
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpmsom_nangia
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpmwilburlo
 
Optimizing Lambda@Edge for Performance and Cost Efficiency (CTD405-R2) - AWS ...
Optimizing Lambda@Edge for Performance and Cost Efficiency (CTD405-R2) - AWS ...Optimizing Lambda@Edge for Performance and Cost Efficiency (CTD405-R2) - AWS ...
Optimizing Lambda@Edge for Performance and Cost Efficiency (CTD405-R2) - AWS ...Amazon Web Services
 

Similar a Angular mix chrisnoring (20)

Reactive application using meteor
Reactive application using meteorReactive application using meteor
Reactive application using meteor
 
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
 
Sst hackathon express
Sst hackathon expressSst hackathon express
Sst hackathon express
 
Reactive Application Using METEOR
Reactive Application Using METEORReactive Application Using METEOR
Reactive Application Using METEOR
 
apidays Australia 2022 - Spinning Your Drones with Cadence Workflows and Apac...
apidays Australia 2022 - Spinning Your Drones with Cadence Workflows and Apac...apidays Australia 2022 - Spinning Your Drones with Cadence Workflows and Apac...
apidays Australia 2022 - Spinning Your Drones with Cadence Workflows and Apac...
 
Angular 2 observables
Angular 2 observablesAngular 2 observables
Angular 2 observables
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in react
 
Universal JS Applications with React
Universal JS Applications with ReactUniversal JS Applications with React
Universal JS Applications with React
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
TPSE Thailand 2015 - Rethinking Web with React and Flux
TPSE Thailand 2015 - Rethinking Web with React and FluxTPSE Thailand 2015 - Rethinking Web with React and Flux
TPSE Thailand 2015 - Rethinking Web with React and Flux
 
Ring: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic ClojureRing: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic Clojure
 
Running Serverless at The Edge (CTD302) - AWS re:Invent 2018
Running Serverless at The Edge (CTD302) - AWS re:Invent 2018Running Serverless at The Edge (CTD302) - AWS re:Invent 2018
Running Serverless at The Edge (CTD302) - AWS re:Invent 2018
 
Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017
 
Spinning your Drones with Cadence Workflows and Apache Kafka
Spinning your Drones with Cadence Workflows and Apache KafkaSpinning your Drones with Cadence Workflows and Apache Kafka
Spinning your Drones with Cadence Workflows and Apache Kafka
 
Traffic Management In The Cloud
Traffic Management In The CloudTraffic Management In The Cloud
Traffic Management In The Cloud
 
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and ScalaWriting highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
 
AngularJS Basics
AngularJS BasicsAngularJS Basics
AngularJS Basics
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Optimizing Lambda@Edge for Performance and Cost Efficiency (CTD405-R2) - AWS ...
Optimizing Lambda@Edge for Performance and Cost Efficiency (CTD405-R2) - AWS ...Optimizing Lambda@Edge for Performance and Cost Efficiency (CTD405-R2) - AWS ...
Optimizing Lambda@Edge for Performance and Cost Efficiency (CTD405-R2) - AWS ...
 

Más de Christoffer Noring (20)

Azure signalR
Azure signalRAzure signalR
Azure signalR
 
Game dev 101 part 3
Game dev 101 part 3Game dev 101 part 3
Game dev 101 part 3
 
Game dev 101 part 2
Game dev 101   part 2Game dev 101   part 2
Game dev 101 part 2
 
Game dev workshop
Game dev workshopGame dev workshop
Game dev workshop
 
Deploying your static web app to the Cloud
Deploying your static web app to the CloudDeploying your static web app to the Cloud
Deploying your static web app to the Cloud
 
IaaS with ARM templates for Azure
IaaS with ARM templates for AzureIaaS with ARM templates for Azure
IaaS with ARM templates for Azure
 
Learning Svelte
Learning SvelteLearning Svelte
Learning Svelte
 
Ng spain
Ng spainNg spain
Ng spain
 
Angular Schematics
Angular SchematicsAngular Schematics
Angular Schematics
 
Design thinking
Design thinkingDesign thinking
Design thinking
 
Keynote ijs
Keynote ijsKeynote ijs
Keynote ijs
 
Vue fundamentasl with Testing and Vuex
Vue fundamentasl with Testing and VuexVue fundamentasl with Testing and Vuex
Vue fundamentasl with Testing and Vuex
 
Ngrx slides
Ngrx slidesNgrx slides
Ngrx slides
 
Kendoui
KendouiKendoui
Kendoui
 
Graphql, REST and Apollo
Graphql, REST and ApolloGraphql, REST and Apollo
Graphql, REST and Apollo
 
Angular 2 introduction
Angular 2 introductionAngular 2 introduction
Angular 2 introduction
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
 
Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
Angular modules in depth
Angular modules in depthAngular modules in depth
Angular modules in depth
 

Último

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 

Último (20)

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 

Angular mix chrisnoring

  • 1. How SPAs got their groove back Christoffer Noring Google Developer Expert @chris_noring
  • 2. © AngularMIX All rights reserved. https://www.angularmix.com Speaker: Christoffer Noring  Google Developer Expert  Telerik Developer Expert ( NativeScript )  Fullstack Developer at Digital McKinsey  London Javascript meetup Organizer  Author of RxJS Ultimate
  • 3. © AngularMIX All rights reserved. https://www.angularmix.com Introduction  Overview  The lost groove  Async and Callback Hell  The limitations of Promises  Introducing the App fu  RxJS beginner to master  Everything is not Response/ Request  Web Sockets, Socket.io  E.g Updated feeds and polling, Earthquake API, Firebase  All together now – The Feed pattern We all need a Rob in a our lives
  • 4. © AngularMIX All rights reserved. https://www.angularmix.com Why should I care? Remember, we write code for humans Knowing RxJS and how to use it Angular will: Make you write less code Make less mistakes that leads to memory leaks Make you write simpler code that is easier to maintain
  • 5. © AngularMIX All rights reserved. https://www.angularmix.com We’ve lost our direction ( groove )  Dealing with async code is painful  Our paradigm is usually how over what = we write too much code
  • 6. © AngularMIX All rights reserved. https://www.angularmix.com Async history callback hell getData('url', data => { getMoreData('url2/'+ data.id, (moreData) => { getEvenMoreData('url3' + moreData.id, (evenMoreData) => { /* do something*/ }); }); }); Pain, so much pain
  • 7. © AngularMIX All rights reserved. https://www.angularmix.com Async history enter Promises getData() .then( getMoreData ) .then( getEvenMoreData ) .catch( handleError ); Now we are talking, readable async
  • 8. © AngularMIX All rights reserved. https://www.angularmix.com Async present day async/await async function get () { let data = await getData('url'); let moreData = await getMoreData('url2' + data.id); let evenMore = await getEvenMore('url3',moreData.id); return evenMore; } get().then( data => console.log( 'data', data )); Everything is great or?
  • 9. © AngularMIX All rights reserved. https://www.angularmix.com Promises are limited what to use for complex scenarios?  Returns one value  Hard to retry  No cancellation  Doesn’t mix easily with other async concepts
  • 10. © AngularMIX All rights reserved. https://www.angularmix.com There is a better to way to do async and its part of Angular – RxJS from Daniel La Russo to Miyagi
  • 11. © AngularMIX All rights reserved. https://www.angularmix.com 1 2 3 Time Observable – stream of data over time
  • 12. © AngularMIX All rights reserved. https://www.angularmix.com Observables let stream$ = Observable.create( observer => { observer.next( 1 ); }); stream$.subscribe( data => console.log('data', data) ); Generate value here Subscribe here
  • 13. © AngularMIX All rights reserved. https://www.angularmix.com Observables + error let stream$ = Observable.create( observer => { observer.next( 1 ); observer.error('err'); }); stream$.subscribe( data => console.log('data', data), err => console.error('err', err) // err ); Error produced Subscribe to error here
  • 14. © AngularMIX All rights reserved. https://www.angularmix.com Observables - completion let stream$ = Observable.create( observer => { observer.next( 1 ); observer.complete(); }); stream$.subscribe( data => console.log('data', data), err => console.error('err', err), () => console.log('complete') ); Complete the stream Subscribe to complete No more value will be generated
  • 15. © AngularMIX All rights reserved. https://www.angularmix.com let stream$ = Observable.create( observer => { let counter = 0; let id = setInterval(() => observer.next(counter++), 1000); return function(){ clearInterval(id); } }); let subscription = stream$.subscribe( data => console.log(‘data’, data) ); setTimeout(() => subscription.unsubscribe()); Cancelling aka unsubscribing Cleaning up resources Define a clean up method
  • 16. © AngularMIX All rights reserved. https://www.angularmix.com But mostly because Kobra Kai says we can’t Knowledge is understanding how to build it, So let’s build our own RxJS
  • 17. © AngularMIX All rights reserved. https://www.angularmix.com  create() operator  subscribe()  unsubscribe()  adding a filter() operator What to build
  • 18. © AngularMIX All rights reserved. https://www.angularmix.com We should have a behaviour function that takes an observer as a parameter We should have a create method on our Observable class We should have an Observable class let stream$ = Observable.create( observer => { observer.next( 1 ); }); Create a stream
  • 19. © AngularMIX All rights reserved. https://www.angularmix.com create() needs to return an Observable instance and save the behaviour function class Observable { constructor( behaviourFn ) { this.behaviourFn = behaviourFn; } create( behaviourFn ) { return new Observable(behaviourFn); } } Observer class
  • 20. © AngularMIX All rights reserved. https://www.angularmix.com Data callback We need to define an Observer class class Observable { constructor( behaviourFn ) { this.behaviourFn = behaviourFn; } create(behaviourFn) { return new Observable(behaviourFn); } subscribe( dataFn ) { behaviourFn( observer ); } } stream$.subscribe( data => console.log(data)); And this guy, dataFn needs to go somewhere Subscribe to the stream
  • 21. © AngularMIX All rights reserved. https://www.angularmix.com class Observer { constructor( dataFn ) { this.dataFn = dataFn; } next(val) { this.dataFn( val ); } } When we call next(), we need to call dataFn() Observer class
  • 22. © AngularMIX All rights reserved. https://www.angularmix.com class Observable { constructor( behaviourFn ) { this.behaviourFn = behaviourFn; } create(behaviourFn) { return new Observable(behaviourFn); } subscribe( dataFn ) { let observer = new Observer( dataFn ); behaviourFn( observer ); } } provide dataFn() to Observer so it may be used when calling .next() Update Observable class
  • 23. © AngularMIX All rights reserved. https://www.angularmix.com let stream$ = Observable.create( observer => { observer.next(1); observer.next(2); }); stream$.subscribe( data => console.log(‘sub1’, data)); // Sub1 1, Sub1 2 stream$.subscribe( data => console.log(‘sub2’, data)); // Sub2 1,Sub 2 2 It works!! Put it to the test
  • 24. © AngularMIX All rights reserved. https://www.angularmix.com We are one with the stream
  • 25. © AngularMIX All rights reserved. https://www.angularmix.com let stream$ = Observable.create( observer => { let counter = 0; let id = setInterval(() => { observer.next(counter++); }, 1000); return function() { clearInterval(id); } }); Let’s create something worth unsubscribing to Let’s define a clean up method Add unsubscribe
  • 26. © AngularMIX All rights reserved. https://www.angularmix.com class Observable { constructor( behaviourFn ) { this.behaviourFn = behaviourFn; } create(behaviourFn) { return new Observable(behaviourFn); } subscribe( dataFn ) { let observer = new Observer( dataFn ); let cleanUpFn = behaviorFn( observer ); return { unsubscribe : cleanUpFn }; } } behaviourFn IS our clean up function, just return it from the unsubscribe() method Let’s update Observable class
  • 27. © AngularMIX All rights reserved. https://www.angularmix.com let stream$ = Observable.create( observer => { let counter = 0; let id = setInterval(() => { observer.next(counter++); }, 1000); return function() { clearInterval(id); } }); stream$.unsubscribe(); This is called When we call this And using it
  • 28. © AngularMIX All rights reserved. https://www.angularmix.com Cleanup successful
  • 29. © AngularMIX All rights reserved. https://www.angularmix.com Summary so far  Observables  Observer  Unsubscribe We know how to build
  • 30. © AngularMIX All rights reserved. https://www.angularmix.com Wisdom is to NOT build it, because other people do it better And there is a GitHub project already, so contribute
  • 31. © AngularMIX All rights reserved. https://www.angularmix.com Operators The thing that empowers Observables
  • 32. © AngularMIX All rights reserved. https://www.angularmix.com Operators Operators can: - Operate on your data - Decide the speed of the stream - Combine streams - Change streams And much more let stream$ = Rx.Observable .of(1, 2, 3); .operator() .operator() .operator(); Define your stream Apply operator after operator
  • 33. © AngularMIX All rights reserved. https://www.angularmix.com Operators- categories Construction Conversion Combination Mathematical Time Grouping
  • 34. © AngularMIX All rights reserved. https://www.angularmix.com There is an operator for everything let stream$ = Rx.Observable .of(1,2,3) .map( ) .filter() .toPromise() .then( data => console.log(data) ) Don’t make bunny sad though Even for converting Observable to Promise
  • 35. © AngularMIX All rights reserved. https://www.angularmix.com Operators- build it yourself
  • 36. © AngularMIX All rights reserved. https://www.angularmix.com class Observable { constructor( behaviour ) { this.behaviour = behaviour; } filter(fnFilter) { let obs = new FilterableObservable(this.behaviour, fnFilter); return obs; } static create( behaviour ) { return new Observable( behaviour ); } subscribe( fnData ) { let observer = new Observer(fnData); this.behaviour( observer ); } } Add filter() – update our Observable class We need a new type of Observable We send in behaviour and filter function
  • 37. © AngularMIX All rights reserved. https://www.angularmix.com class FilterableObservable extends Observable { constructor(behaviour, filter) { super(behaviour); this.filter = filter; } subscribe(fnData) { let observer = new Observer( fnData ); observer.next = (val) => { if(this.filter(val)){ fnData( val ); } }; this.behaviour( observer ); } } FilterableObservable For every value, check with our filter() if it should be emitted We even know how to build Operators now
  • 38. © AngularMIX All rights reserved. https://www.angularmix.com Before talking about Angular with RxJS Wrap Observable Change from one stream to the next Let’s learn a couple of more concepts
  • 39. © AngularMIX All rights reserved. https://www.angularmix.com let stream$ = Rx.Observable.create(observer => { someAsyncFunction((val) => { observer.next( val ); observer.complete(); }); }); stream$.subscribe( data => { console.log('async data', data); }); Wrapping, fulfill the contract function someAsyncFunction(cb){ setTimeout(() => { cb('some value'); },3000); } Allows us to make anything async part of Observables and RxJS A callback function turned into an Observable
  • 40. © AngularMIX All rights reserved. https://www.angularmix.com let elem = document.getElementById('text'); let stream = Rx.Observable .fromEvent(elem,'keyup') .switchMap( data => { return new Rx.Observable.of('some data back based on: '+ data); }); stream.subscribe( data => { console.log('data', data); }) Change from one type of stream to the next flatMap(), switchMap() keyUp stream Change into new stream
  • 41. © AngularMIX All rights reserved. https://www.angularmix.com Working with switchMap/flatMap is a key concept You are able to divide up your code into multiple stream, Aka you are able to break down the problem keykey key AJAX AJAX AJAX Combine different types of streams to build your algorithm It will also make it easier to isolate errors into a specific stream
  • 42. © AngularMIX All rights reserved. https://www.angularmix.com Angular comes with RxJS in everything
  • 43. © AngularMIX All rights reserved. https://www.angularmix.com Angular comes with RxJS an async scenario that grows with you class Service{ constructor(private http:HttpClient) {} getData() { return this.httpClient .get('url') .map( this.mapPeople ); } mapPeople():Array<Person> { return json => json.map( person => new Person(person)); } } Get your HTTP data with HttpClien
  • 44. © AngularMIX All rights reserved. https://www.angularmix.com export class PeopleComponent implements OnInit, implements OnDestroy { people:Array<Person>; subscription; constructor(private srv: Service) {} ngOnInit() { this.subscription = srv.getData() .subscribe( data => this.people = data ); } ngOnDestroy() { this.subscription.unsubscribe(); } } Subscribe Call unsubscribe on destroying component Angular WITHOUT async pipe
  • 45. © AngularMIX All rights reserved. https://www.angularmix.com Angular removes Cancelling with async pipe@Component({ template : ` <div *ngFor="let person of people$ | async"> {{ person.name }} </div> ` }) export class PeopleComponent implements OnInit { people$:Observable<Person>; constructor(private srv: Service) {} ngOnInit() { this.people$ = srv.getData(); } } No more subscribe() Or Unsubscribe()
  • 46. © AngularMIX All rights reserved. https://www.angularmix.com class Service{ people: Array<Person>; constructor(private http:HttpClient) {} getData() { return this.httpClient .get('url') .map( this.mapPeople ) .do( data => localStorage.setItem(‘people’,data); ) .catch( err => { let people = localStorage.getItem(‘people’); return of(people !== null ? people : []); }) } } Handle offline with localStorage Save response to cac Retrieve cached response if erroring out
  • 47. © AngularMIX All rights reserved. https://www.angularmix.com class Service{ constructor(private http:HttpClient) {} getData() { return this.httpClient .get('url') .map( this.mapPeople ) .retryWhen( err => err.delay(200) ) .take(noOfAttemptsBeforeGivingUp) } } Handle shaky connections with retryWhen Delays each attempt with 200ms, Also retries x times Ok to do, but stream finishes, after x attempts
  • 48. © AngularMIX All rights reserved. https://www.angularmix.com class Service{ constructor(private http:HttpClient) {} getData() { return this.httpClient .get('url') .map( this.mapPeople ) .retryWhen( err => { err .scan((errCount, err) => if(errCount === 2) { throw ‘giving up’ } else { return errCount + 1; } ,0) .delay(200 * errCount) // progressive increase time }) .take(noOfAttemptsBeforeGivingUp) // 404,500 } } Handle shaky connections better solution stream$.subscribe( data => console.log( 'err stream', data ), err => console.log( 'erroring out after x retries', respondWithCachedData) ) errorCount, delay and termination Sort out why it failed to see wether it is worth retrying
  • 49. © AngularMIX All rights reserved. https://www.angularmix.com From a service to a feed What is a feed? Why do we want a feed? There might be more than one component wanting to consume the data We don’t want to do unnecessary HTTP calls An exposed Observable that can have many subscribers
  • 50. © AngularMIX All rights reserved. https://www.angularmix.com From a service to a feed class Service{ people: Array<Person>; constructor(private http:HttpClient) { this.fetchData(); } fetchData() { return this.httpClient .get('url') .map( this.mapPeople ) .subscribe( data => this.people = data ); } } @Component({}) export class PeopleComponent implements OnInit { private people: Array<Person>; constructor(private srv: PersonService) { } get people() { return this.srv.people; } } We can do this with a minimum of RxJS, Trust in Angulars change detection Use this for Change Detection to trigger
  • 51. © AngularMIX All rights reserved. https://www.angularmix.com What did we learn on services? We should handle offline We should handle shaky connections How to build a feed service
  • 52. © AngularMIX All rights reserved. https://www.angularmix.com There is more than HTTP  HTTP  Web Sockets, Full Duplex connections  Firebase  Socket.io  HTTP + Polling feeds And it affects how we write our service and consumes it
  • 53. © AngularMIX All rights reserved. https://www.angularmix.com Building our service add Socket.io import * as io from 'socket.io-client'; export class TaskService { subscription; tasks:Task[] = []; constructor(private http:Http) { this.fetchData(); this.socket = io(this.url); this.socket.on('task', (data) => { this.tasks = [ ...this.tasks, data ]; }); } private fetchData() { /* omitted */ } } We can use our feed pattern, but what if we want to listen to changes? And display CSS
  • 54. © AngularMIX All rights reserved. https://www.angularmix.com Two different approaches we want to know when a change happens One of the few cases when a Subject might be need .share() .replay(1) BehaviourSubject
  • 55. © AngularMIX All rights reserved. https://www.angularmix.com Adding BehaviourSubject export class TaskService { private internalStore:BehaviourSubject; constructor() { this.internalStore = new BehaviourSubject([]); } get store() { return this.internalStore.asObservable(); } private fetchTasks(){ this.http .get('/data/tasks.json') .map(response => response.json()) .map(this.mapTasks) .do( data => { this._store.next( data ); localStorage.setItem('tasks', JSON.stringify(data)) }) .catch( err => { return Rx.Observable.of(this.fetchLocalStorage()); }); } } Initialize Subject Expose as Observable, aka defensive coding Gives us start data, also remembers last emitted
  • 56. © AngularMIX All rights reserved. https://www.angularmix.com Building our service consuming our service @Component({}) export class TaskComponent implements OnInit { constructor(private srv: TaskService) {} ngOnInit() { this.srv.store.subscribe( tasks => { // tasks where updated somehow, show CSS }); } } Only when we care about changes, REMEMBER most of the time we don’t need a Subject
  • 57. © AngularMIX All rights reserved. https://www.angularmix.com Earthquake API HTTP Polling  The title (28 pt) uses the dark red (the 4th color in the template)  The subtitle is 1 size smaller (24 pt) and should always uses the theme gray color (2nd color in the template)  Text here is 20 pt  18 pt  16 pt
  • 58. © AngularMIX All rights reserved. https://www.angularmix.com Mixing different async concepts Rich composition Naive Little better Angular version
  • 59. © AngularMIX All rights reserved. https://www.angularmix.com First naive approach let elem = document.getElementById('text'); let stream = Rx.Observable .fromEvent(elem,'keyup') .map( ev => ev.key ) .filter( key => { return elem.value.length > 3; }) .switchMap( data => { return new Rx.Observable.of('some data back based on: '+ data); }); Only do something when We have enough entered charac From keystream to AJAX stream, playing nice with other async concepts – rich composition
  • 60. © AngularMIX All rights reserved. https://www.angularmix.com Better approach let elem = document.getElementById('text'); let stream = Rx.Observable .fromEvent(elem,'keyup') .map( ev => ev.key ) .debounceTime(500) .switchMap( data => { return new Rx.Observable.of('some data back based on: '+ data); }); Wait til the user stopped typing for 500ms
  • 61. © AngularMIX All rights reserved. https://www.angularmix.com Angular approach - service export class ServiceService { constructor(private http: HttpClient) {} httpSearch(inputText: string) { return this.http.get('url?query=${inputText}'); } } A simple http.get() call
  • 62. © AngularMIX All rights reserved. https://www.angularmix.com Angular approach - component <input type="text" [formControl] = "input" class="form-control” /> <div *ngFor="let term in result | async"> {{term}} </div> @Component({}) export class SearchComponent { result$:Observable; input = new FormControl(); constructor(private srv:SearchService) { this.result$ = this.input .valueChanges .debounceTime(500) .distinctUntilChanged() .switchMap(inputText => this.srv.httpSearch(inputText)) } } Capture change, when it happens
  • 63. © AngularMIX All rights reserved. https://www.angularmix.com Summary  We actually understand how to build RxJS  Angular helps out with async pipe and its own change detection  RxJS does a lot of the heavy lifting thanks to  Operators for manipulating data  Operators for advanced error scenarios such as retry etc..  Some constructs in RxJS should be sparsely used like Subject  We can rich composition, cause everything async can be made into an Observable
  • 64. © AngularMIX All rights reserved. https://www.angularmix.com My free gitbook on RxJS  angular.io/resources RxJS 5 Ultimate  Help me make it better or just tell your friends  Power to the community
  • 65. © AngularMIX All rights reserved. https://www.angularmix.com Thank you promise .retry(4) .kungfuKid(1) @chris_noring