20.03.2019, Angular Brisbane
Senior Frontend Developer @Scalac
https://slides.com/ktrz/ng-brisbane-rx-cs
const source$: Observable<number> = timer(1000);
const result$: Observable<number> = source$
.pipe(
filter(v => v % 3 === 1),
map(v => v * 7)
);
<button (click)="clicks$.next($event)">
Add order
</button>
<app-coffee-items [items]="state$ | async">
</app-coffee-items>
export class AppComponent {
clicks$: Subject<Event> = new Subject();
state$: Observable<CoffeeRequest[]> = of();
}
clicks$: Subject<Event> = new Subject();
coffeeReqs$: Observable<CoffeeRequest> =
this.clicks$.pipe(
map(idGenerator()), // generates unique id
map(id => ({
id: id,
status: CoffeeRequestStatusValue.requested,
}))
);
state$: Observable<CoffeeRequest[]> =
this.coffeeReqs$.pipe(
???
);
clicks$: Subject<Event> = new Subject();
coffeeReqs$: Observable<CoffeeRequest> =
this.clicks$.pipe(
map(idGenerator()), // generates unique id
map(createCoffeeRequest),
// maps to {id, status: requested}
);
state$: Observable<CoffeeRequest[]> =
this.coffeeReqs$.pipe(
???
);
state$: Observable<CoffeeRequest[]> =
this.coffeeReqs$.pipe(
scan((
state: CoffeeRequest[],
val: CoffeeRequest) => [...state, val],
[]),
);
state$: Observable<CoffeeRequest[]> =
this.coffeeReqs$.pipe(
scan((
state: CoffeeRequest[],
val: CoffeeRequest) => [...state, val],
[]),
startWith([])
);
coffeeReqs$: Observable<CoffeeRequest> =
this.clicks$.pipe(
map(idGenerator()), // generates unique id
map(id => ({
id: id,
status: CoffeeRequestStatusValue.requested,
}))
);
coffeeMaking$: Observable<CoffeeRequest> =
this.coffeeReqs$.pipe(assignBarista());
export class AppComponent {
coffeeReqs$: Observable<CoffeeRequest> =
prevCoffeeRequest$.pipe(share());
coffeeMaking$: Observable<CoffeeRequest> =
this.coffeeReqs$.pipe(
delay(1000),
map((request: CoffeeRequest): CoffeeRequest => ({
...request,
status: CoffeeRequestStatusValue.making,
}))
);
coffeeMaking$: Observable<CoffeeRequest> =
this.coffeeReqs$.pipe(
delay(1000),
map((request: CoffeeRequest): CoffeeRequest => ({
...request,
status: CoffeeRequestStatusValue.making,
}))
);
const setStatus = (status: CoffeeRequestStatusValue) =>
map((request: CoffeeRequest): CoffeeRequest => ({
...request,
status,
}));
coffeeMaking$: Observable<CoffeeRequest> =
this.coffeeReqs$.pipe(
delay(1000),
);
const setStatus = (status: CoffeeRequestStatusValue) =>
map((request: CoffeeRequest): CoffeeRequest => ({
...request,
status,
}));
coffeeMaking$: Observable<CoffeeRequest> =
this.coffeeReqs$.pipe(
delay(1000),
setStatus(CoffeeRequestStatusValue.making)
);
state$: Observable<CoffeeRequest[]> =
merge(this.coffeeReqs$, this.coffeeMaking$).pipe(
scan((
state: CoffeeRequest[],
val: CoffeeRequest) => [...state, val],
[]),
startWith([])
);
}
coffeeReqs$: Observable<CoffeeRequest> =
this.clicks$.pipe(
map(idGenerator()), // generates unique id
map(createCoffeeRequest),
// maps to {id, status: requested}
);
coffeeMaking$: Observable<CoffeeRequest> =
this.coffeeReqs$.pipe(
delay(1000),
setStatus(CoffeeRequestStatusValue.making)
);
state$: Observable<CoffeeRequest[]> =
merge(this.coffeeReqs$, this.coffeeMaking$).pipe(
scan((
state: CoffeeRequest[],
val: CoffeeRequest) => [...state, val],
[]),
startWith([])
);
}
export class AppComponent {
coffeeReqs$: Observable<CoffeeRequest> = /* */
coffeeMaking$: /* */
state$: Observable<CoffeeRequest[]> =
merge(this.coffeeReqs$, this.coffeeMaking$).pipe(
scan((
state: { [key: number]: CoffeeRequest },
val: CoffeeRequest) => ({
...state,
[val.id]: val,
}),
{}),
map(state => Object.keys(state)
.map(key => state[key])
.filter(v => !!v)),
startWith([])
);
}
coffeeMaking$: Observable<CofReq> =
this.coffeeReqs$.pipe(
delay(1000),
setStatus(CoffeeRequestStatusValue.making)
);
export interface OperatorFunction<T, R> {
(source: Observable<T>): Observable<R>;
}
const noopOperator = <T>(source: Observable<T>) => source;
const filterAndMultiply = (source: Observable<number>) =>
source.pipe(
filter(v => v % 3 === 1),
map(v => v * 7)
);
const multiplyBy7 = map(v => v * 7)
const multiplyBy7 = (source: Observable<number>) =>
source.pipe(
map(v => v * 7)
);
coffeeMaking$: Observable<CofReq> =
this.coffeeReqs$.pipe(this.assignBarista());
assignBarista(): OperatorFunction<CofReq, CofReq> {
return (source: Observable<CoffeeRequest>) =>
source.pipe(
delay(1000),
setStatus(CoffeeRequestStatusValue.making)
);
}
/* makeCoffee, pickupCoffee */
state$: Observable<CofReq[]> =
merge(
this.coffeeReqs$, this.coffeeMaking$,
this.coffeeDone$, this.coffeePickedUp$)
.pipe(/* scan, map */)
coffeeMaking$: Observable<CofReq> =
this.coffeeReqs$.pipe(
delay(1000),
setStatus(CoffeeRequestStatusValue.making)
);
coffeeDone$: Observable<CofReq> =
this.coffeeMaking$.pipe(this.makeCoffee());
coffeePickedUp$: Observable<CofReq> =
this.coffeeDone$.pipe(this.pickupCoffee());
let's enjoy our coffee...
... as a stream