Patricio Vargas
Software Engineer
Entire programs can be built uniquely around the notion of streams.
RxJS is a library for composing asynchronous and event based programs by using observable sequences.
+
= POWER COUPLE
Compositional: Our view requires data from several sources, we can easily compose data with RxJS.
Watchful: We get notified when our data changes overtime.
Lazy: doesn't start until we subscribe
Error Handler: handle errors
Cancel: We can cancel async actions
Quick to react to user interactions, resistant to failure, reactive to state changes (code watches for state changes and reacts)
-Subscribe
-Pipe through set of operators
-Observer( next, error(), complete)
-Stop steam (unsubscribe)
-Call .complete()
-Use a completing operator
-Throw error
-Unsubscribe
Observable.of([1, 2, 3]).subscribe(x => console.log(x));
//Would print the whole array at once.
///On the other hand, from prints elements one by one.
Observable.from([1, 2, 3]).subscribe(x => console.log(x));
getPosts(query?: object): Post[] {
return from(
this.cdaClient.getEntries({
...Object,
content_type: this.CONFIG.contentTypeIds.angularPost,
query
})
).pipe(map(posts => posts.items));
}
const source = from([1, 2, 3, 4, 5]);
//add 10 to each value
const example = source.pipe(map(val => val + 10));
//output: 11,12,13,14,15
const source = of(1, 2, 3, 4, 5);
const example = source.pipe(
tap(val => {
val = val * 2;
console.log(`On tap: ${val}`);
//What is the output?
}),
);
const subscribe = example.subscribe(val => console.log(val));
//What is the output?
//emit 1,2,3,4,5
const source = of(1, 2, 3, 4, 5);
//take the first emitted value then complete
const example = source.pipe(take(1));
//output ?
import { timer, from, of } from 'rxjs';
import { mergeMap, catchError } from 'rxjs/operators';
//Some code
const example = source.pipe(
mergeMap(_ =>
from(myBadPromise()).pipe(catchError(error => of(`Bad Promise: ${error}`)))
)
);
//output: 'Bad Promise: Rejected'
//Rejected is the value that the stream contains
const subscribe = example.subscribe(val => console.log(val));
categories$ = this.productCategoryService.productCategories$.pipe(
catchError(err => {
this.errorMessageSubject.next(err);
return EMPTY;
})
);
<div class="alert alert-danger" *ngIf="errorMessageSubject | async as errorMessage">
{{ errorMessage }}
</div>
this.httpPost.pipe(switchMap(res => (res.bearerToken) ?
of(this.saveJwt(res.bearerToken)) :
throwError('Valid token not returned')
));
Text
Text
const source = of(1, 2, 3);
// basic scan example, sum over time starting with zero
const example = source.pipe(scan((acc, curr) => acc + curr, 0));
// log accumulated values
// output: 1,3,6
-Improves responsiveness
-Reduces bandwidth and network consumption
-Reduces backend server load
-Reduces redundant computations
//You first get the observable for data:
ngOninit(){
this.data$ = this._jokeService.getData().pipe(shareReplay(1));
}
//Now subscribe multiple times:
public getData(){
this.data$.subscribe();
}
//Your service:
public getData() {
return this.http.get(API_ENDPOINT);
}
-Invalidating the cache on a time interval
-Allowing user to control when the data is refreshed
-Always getting refresh data on update
products$ = this.http.get<Product[]>(this.productsUrl).pipe(
tap(data => console.log('Products: ', JSON.stringify(data))),
catchError(this.handleError)
);
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(this.productsUrl).pipe(
catchError(this.handleError)
);
}
-Leverage the power of Rxjs observables and operators
-Effectively combine streams
-Easy share observables
-Readily react to user action
-Map Id to a string
-Work with multiple data sources
-React to actions
-Simply template code
-LatestFrom: emits any time a new value is emitted from the source stream
-CombineLast: emits any time a new value is emitted from any of the sources them
-ForkJoin: Emits only the last emitted values
of(3,7).pipe(map id=> this.http.get<Supplier>)(`....${id}`))).subcribe();
of(3,7).pipe(map id=> this.http.get<Supplier>)(`....${id}`))).subcribe(o=> o.subscribre());
supplierWithConcatMap$ = of(1, 5, 8).pipe(
tap(id => console.log('concat id ', id)),
concatMap(id => this.http.get<Supplier>(`${this.suppliersUrl}/${id}`))
);
supplierWithMergeMap$ = of(1, 5, 8).pipe(
tap(id => console.log('merge id ', id)),
mergeMap(id => this.http.get<Supplier>(`${this.suppliersUrl}/${id}`))
);
supplierWithSwitchMap$ = of(1, 5, 8).pipe(
tap(id => console.log('swtich id ', id)),
switchMap(id => this.http.get<Supplier>(`${this.suppliersUrl}/${id}`))
);
By Patricio Vargas
Reactive programming in Angular using RxJS