2

Redux-Observable has a dependency on RxJS.

I need to use the filereader function from RxJS-DOM.

https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/doc/operators/filereader.md

It looks like RxJS-DOM contains the same basic set of APIs as RxJS (plus the DOM ones).

Is it possible to ask Redux-Observable to use RxJS-DOM rather than RxJS? Importing both is bloating the size of my build.

  • They claim to have a [procedure to write an adapter](https://redux-observable.js.org/docs/FAQ.html#general-rxjs-v4) for other RX implementations; haven't tried it myself! – Nikos Paraskevopoulos Jul 10 '17 at 15:05

1 Answers1

3

RxJS-DOM aka rx-dom is for RxJS v4, not for v5+. The two are incompatible. The situation is confusing, indeed.

In v5+ there is no official equivalent to fromReader, here's the issue ticket tracking: https://github.com/ReactiveX/rxjs/issues/1223

Although probably not what you want to hear, creating custom Observable wrappers around other APIs should be fairly simple as long as you do understand how Observables fundamentally work. It's a pretty valuable skill to learn, regardless.

fromReader is actually a misnomer since you don't provide it a FileReader, you provide it a File and it internally creates its own FileReader to drain it. So let's say fromFile instead. This is a very basic starting point example:

class FromFileAsTextObservable extends Observable {
  constructor(file, encoding) {
    super();

    this.file = file;
    this.encoding = encoding;
  }

  _subscribe(subscriber) {
    const reader = new FileReader();

    const loadHandler = event => {
      subscriber.next(event.target.result);
      subscriber.complete();
    };

    const errorHandler = event => {
      subscriber.error(event.target.error);
    };

    reader.addEventListener('load', loadHandler, false);
    reader.addEventListener('error', errorHandler, false);

    reader.readAsText(this.file, this.encoding);

    return () => {
      reader.removeEventListener('load', loadHandler, false);
      reader.removeEventListener('error', errorHandler, false);
    };
  }
}

class FromFileFactory {
  constructor(file) {
    this.file = file;
  }

  asText(encoding) {
    return new FromFileAsTextObservable(this.file, encoding);
  }
}

const fromFile = file =>
  new FromFileFactory(file);

const file = new File(['hello world'], 'example.txt', {
  type: 'text/plain',
});

fromFile(file).asText()
  .subscribe(text => console.log(text));

While that's the more flexible way for complex APIs and such, if all you want to do is read a file and handle load/error, you could instead create an anonymous Observable like so:

const fromFileAsText = (file, encoding) => new Observable(subscriber => {
  const reader = new FileReader();

  const loadHandler = event => {
    subscriber.next(event.target.result);
    subscriber.complete();
  };

  const errorHandler = event => {
    subscriber.error(event.target.error);
  };

  reader.addEventListener('load', loadHandler, false);
  reader.addEventListener('error', errorHandler, false);

  reader.readAsText(file, encoding);

  return () => {
    reader.removeEventListener('load', loadHandler, false);
    reader.removeEventListener('error', errorHandler, false);
  };
});

const file = new File(['hello world'], 'example.txt', {
  type: 'text/plain',
});

fromFileAsText(file)
  .subscribe(text => console.log(text));
jayphelps
  • 15,276
  • 3
  • 41
  • 54