Search code examples
javascriptangularrxjsdom-eventsrxjs-observables

Rxjs chain to convert observable<File> to observable<string> (base64)


I have a working code to convert my File object to base64:

let reader = new FileReader();
     reader.readAsDataURL(myFile);
     reader.onload = () => {
         let resultStrOrArrayBuf = reader.result;
         if (!(resultStrOrArrayBuf instanceof ArrayBuffer)) {
            ..do something with resultStrOrArrayBuf
         }
    };

However I do now have to integrate this part to an existing rxjs chain. In the chain I receive the File object and would like to go on with the base64 result of the conversion. However the conversion is done with the help of the onload event. Is there some way to convert this event to a new observable and pass this to the chain?


Solution

  • there is no out of the box method to convert this loaded event to rxjs observable. you will have to make your own operator.

    export const dataUrlToObs = myFile => new Observable<string | ArrayBuffer>(subscriber => {
      const reader = new FileReader();
      reader.readAsDataURL(myFile);
      reader.onload = () => {subscriber.next(reader.result); subscriber.complete(); };
      reader.onerror = () => subscriber.error(reader.error);
      return () => reader.abort(); // cancel function in case you unsubscribe from the obs
    }
    

    it later can be used like this:

    ..chain
    switchMap(myFile => dataUrlToObs(myFile)),
    tap(resultStrOrArrayBuf => {
       if (!(resultStrOrArrayBuf instanceof ArrayBuffer)) {
             ..do something with resultStrOrArrayBuf
       }
    })