RxCoffeeShop

@ktrz__  |      /ktrz

31.01.2019, Angular Wrocław

Chris Trześniewski

Senior Frontend Developer @Scalac

http://slides.com/ktrz/ng-wroclaw-rx-cs

What's an Observable

 

  • Stream
  • Promise on steroids
  • Function that tie observer to a producer

Data delivered over time

 

Operators

Operators

const source$: Observable<number> = timer(1000);

const result$: Observable<number> = source$
  .pipe(
    filter(v => v % 3 === 1),
    map(v => v * 7)
  );

Enough with the theory

 

How can we use it?

The way of coffee

 

  • Make order
  • Barista picks up order
  • Coffee brewing
  • Optionally
    • Heat milk
    • Add milk
  • I pick up coffee

We can code that!

 

Order board

<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(createCoffeeRequest), 
      // maps to {id, status: requested}
    );

  state$: Observable<CoffeeRequest[]> =
    this.coffeeReqs$.pipe(
      scan((
        state: CoffeeRequest[],
        val: CoffeeRequest) => [...state, val],
        []),
      startWith([])
    );

  coffeeMaking$: Observable<CoffeeRequest> =
    this.coffeeReqs$.pipe(assignBarista());
 
  state$: Observable<CoffeeRequest[]> =
    merge(this.coffeeReqs$, this.coffeeMaking$).pipe(
      scan((
        state: CoffeeRequest[],
        val: CoffeeRequest) => [...state, val],
        []),
      startWith([])
    );
}
export class AppComponent {
  coffeeReqs$: Observable<CoffeeRequest> =
    prevCoffeeRequest$.pipe(share());

  coffeeMaking$: Observable<CoffeeRequest> =
    this.coffeeReqs$.pipe(
      delay(1000),
      setStatus(CoffeeRequestStatusValue.pickedUp)
    );
 
  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<CoffeeRequest> =
    this.coffeeReqs$.pipe(this.assignBarista());
 
  assignBarista(): OperatorFunction<CofReq, CofReq> {
    return (source: Observable<CoffeeRequest>) =>
      source.pipe(
        delay(1000),
        setStatus(CoffeeRequestStatusValue.pickedUp)
      );
  }
  /* makeCoffee, pickupCoffee */
state$: Observable<CofReq[]> =
    merge(
      this.coffeeReqs$, this.coffeeMaking$,
      this.coffeeDone$, this.coffeePickedUp$)
    .pipe(/* scan, map */)
  coffeeMaking$: Observable<CoffeeRequest> =
    this.coffeeReqs$.pipe(
      delay(1000),
      setStatus(CoffeeRequestStatusValue.pickedUp)
    );
  coffeeDone$: Observable<CoffeeRequest> =
    this.coffeeMaking$.pipe(this.makeCoffee());
  coffeePickedUp$: Observable<CoffeeRequest> =
    this.coffeeDone$.pipe(this.pickupCoffee());

What more...

Live coding

Thank you!

 

Any question?

 

Made with Slides.com