Rob
Rob

Reputation: 7237

Upgrading from RxJS5 to RxJS6

I'm having an issue upgrading from RxJS5 to version 6. I've got the following code:

  private captureEvents(canvasEl: HTMLCanvasElement) {

    Observable
      .fromEvent(canvasEl, 'mousedown')
      .switchMap((e) => {
        return Observable
          .fromEvent(canvasEl, 'mousemove')
          .takeUntil(Observable.fromEvent(canvasEl, 'mouseup'))
          .pairwise()
      })
      .subscribe((res: [MouseEvent, MouseEvent]) => {
        const rect = canvasEl.getBoundingClientRect();

        const prevPos = {
          x: res[0].clientX - rect.left,
          y: res[0].clientY - rect.top
        };

        const currentPos = {
          x: res[1].clientX - rect.left,
          y: res[1].clientY - rect.top
        };

        this.drawOnCanvas(prevPos, currentPos);
      });
  }

But when I upgrade to RxJS6 I get the following error:

Property 'fromEvent' does not exist on type 'typeof Observable'.

I tried to change my imports from this (RxJS5):

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/takeUntil';
import 'rxjs/add/operator/pairwise'; 
import 'rxjs/add/operator/switchMap';

To this (RxJS6):

import { Observable, fromEvent } from 'rxjs';
import { switchMap, takeUntil, pairwise } from 'rxjs/operators';

This was my best attempt up upgrading the code:

  private captureEvents(canvasEl: HTMLCanvasElement) {

    const obsMouseDown = fromEvent(canvasEl, 'mousedown').pipe(
      switchMap((e) => {
        const obsMouseMove = fromEvent(canvasEl, 'mousemove').pipe(
          takeUntil(a => {
            const obsMouseUp = fromEvent(canvasEl, 'mouseup').pipe(
              pairwise()
            );
            return obsMouseUp;
          }));

        return obsMouseMove;
      }))
      .subscribe((res: [MouseEvent, MouseEvent]) => {
        const rect = canvasEl.getBoundingClientRect();

        const prevPos = {
          x: res[0].clientX - rect.left,
          y: res[0].clientY - rect.top
        };

        const currentPos = {
          x: res[1].clientX - rect.left,
          y: res[1].clientY - rect.top
        };

        this.drawOnCanvas(prevPos, currentPos);
      });
  }

But this isn't working - I get an error for the "takeUntil" code:

Argument of type '(a: any) => Observable<[Event, Event]>' is not assignable to parameter of type 'Observable'

plnkr example of original code here:
https://embed.plnkr.co/QSvJxi/

Upvotes: 0

Views: 531

Answers (3)

Mark Hughes
Mark Hughes

Reputation: 7374

I think you are actually very close, I think you have your pipes too "deep" though - remember you can chain as many operators as you need together in a pipe, so your inner mouse-move-until-mouse-up switchmap should look more like this:

private captureEvents(canvasEl: HTMLCanvasElement) {

    const obsMouseDown = fromEvent(canvasEl, 'mousedown').pipe(
        switchMap((e) => {
            return fromEvent(canvasEl, 'mousemove').pipe(
              takeUntil(a => fromEvent(canvasEl, 'mouseup')),
              pairwise()
            ));
        }))
        .subscribe((res: [MouseEvent, MouseEvent]) => {
            // snip
        });
}

Upvotes: 1

Taha Zgued
Taha Zgued

Reputation: 1108

For some reason your plnkr didn't work for me but I'll try my best to provide an answer. I think you should do 2 things here for starter. Try initializing your Observables so it's easier to call them and subscribe to them like so:

const mousedown$ = fromEvent(pauseButton, 'mousedown');
const mouseup$ = fromEvent(resumeButton, 'mouseup');
const mousemove$ = fromEvent(resumeButton, 'mousemove');

The second thing you should pipe your operators now with Rxjs 5 & 6, like so, And subscribe to all your events

mousedown$.pipe(
    switchMap(res => {
       mousemove$.pipe(//Whatever Operators and subscribitions to other events).subscribe(...)
    }),
    map(// Whatever you want back from your event)
  ).subscribe(...)

I refer to you the documentation links switchMap && takeUntil . As many syntaxes are changing in Rxjs don't be shy to brows the documentation, there is nothing better.

Upvotes: 1

Taha Zgued
Taha Zgued

Reputation: 1108

fromEvent 

Now is already of type Observable. You don't need the chain it to an Observebal instead you can call it directly and affect it to a variable or better a const. Like below:

const source = fromEvent(document, 'click');

as for the import, you figured it right

import { fromEvent } from 'rxjs';

Upvotes: 1

Related Questions