user458975
user458975

Reputation: 35

How to export the value of an observable and assign to a variable?

I'm trying to assign a value of an observable to a variable but it returns Undefined.

Is there any way to assign this value to a variable outside the subscribe method?

new Observable((observer) => {
  const reader = new FileReader();
  reader.onload = () => {
    observer.next(reader.result);
    observer.complete();
  };
  reader.onerror = e => observer.error(e);
  reader.readAsDataURL(file);
  return () => {
    if (reader.readyState === 1) {
      reader.abort();
    }
  };
});
let result;
getBase64(blob)
 .subscribe((base64) => { result = base64; });
return result;

Upvotes: 1

Views: 843

Answers (1)

Jono Job
Jono Job

Reputation: 3048

You may be running into the difference between synchronous and asynchronous programming.

In a nutshell, result is returned immediately, while observer.next is only called once the onload function is executed some time in the future which might be immediately, seconds later, or even never.

So once you try to do something asynchronous, you effectively have to execute the result handler as a different block of code.

If I were wanting to get the result from a FileReader, I'd usually go for a promise approach, (rather than an Observable) as I'm only expecting a single value (or an error). While similar, Promises are a bit simpler, while Observables are more powerful.

A rough example:

function getFileContents(file) {
  return new Promise((resolve, reject) => {
    var reader = new FileReader();
    reader.onload = evt => resolve(evt.target.result);
    reader.onerror = err => reject(err);
    reader.readAsText(file);
  });
}

This function will give you back a Promise<string> (a promise that contains a string). You still need to "unwrap" the promise to get the internal value though (using then or async/await-style programming).

If you are really sure you want an observable, then I'd probably still use the above promise function, but call it like this:

import { from } from 'rxjs'; 

function getFileContents(file) {
  ...
}

const myObservable = from(getFileContents(fileBlob));

Upvotes: 1

Related Questions