0

So using native JS I can read a text based blob as follows:

const getBlob = () =>
      let url = // some endpoint that returns a blob
      let xhr = new XMLHttpRequest();
      xhr.responseType = 'blob';
      xhr.onload = function(event) {
        let blob = xhr.response;
        let reader = new FileReader();
        reader.addEventListener('loadend', (e) => {
          let read = e.srcElement.result;
          console.log(read); <-- text I want
        });
        let read = reader.readAsText(blob);
        console.log(blob)
        console.log(read)
      }
      xhr.open('GET', url);
      xhr.send();
}

However, I would like my function to return the variable read

My question is if it is possible to rewrite this with async / await to do so.

I ask because I am not sure how that would work with reader.addEventListener(...) which is inside xhr.onload

SumNeuron
  • 4,850
  • 5
  • 39
  • 107
  • "I would like my function to return the variable read". That is not possible. Your function returns before `read` has been assigned a value and making it `async` wouldn't change that. You could make it return a Promise that resolves to the value of `read` though. – Paul Apr 17 '19 at 19:33
  • @Paulpro that is what I felt... could you please demonstrate how? – SumNeuron Apr 17 '19 at 19:33
  • 1
    If you're okay with dropping support for older browsers the easiest and cleanest way is to use [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) instead of `XMLHttpRequest`. Otherwise you will probably want to use `return new Promise( (resolve, reject) => { ... } )` where you replace `...` with your current function body, and then use `resolve( read );` where you have your `<-- text I want` note. – Paul Apr 17 '19 at 19:38
  • Then the caller can use `getBlob( ).then( result => { console.log( result ); } );` (`result` will contain the value the Promise resolved to). – Paul Apr 17 '19 at 19:38
  • 2
    You can take a look to an old answer: [How do I promisify native XHR?](https://stackoverflow.com/a/30008115) – Kalizi Apr 17 '19 at 19:41
  • 1
    @Kalizi thank you for linking the informative post – SumNeuron Apr 18 '19 at 07:39
  • @Paulpro what would / where would I reject? I decided I would just promisify the `reader` chunk, so that resolves `read` but what is rejected? – SumNeuron Apr 18 '19 at 07:40
  • You would reject if there is an error, such as the Ajax request returning an unexpected response or timing out. – Paul Apr 18 '19 at 12:11
  • You're not required to call reject every time you create a Promise, but it's a good practice. In particular if the async operation can fail. – Paul Apr 18 '19 at 12:12

1 Answers1

0

try use, instead, Blob.text(); // returns a Promise. It is an updated method than FileReader.readAsText. However, it is unsupported by quite a number of browsers.

  • Blob.text() returns a promise, whereas FileReader.readAsText() is an event based API.
  • Blob.text() always uses UTF-8 as encoding, while FileReader.readAsText() can use a different encoding depending on the blob's type and a specified encoding name.

enter image description here

Answer summarized from here

**** My advice is to keep using the old method ****

AbuDawood
  • 745
  • 7
  • 22
  • 1
    The new read method is now supported everywhere but IE, which is dead anyway, and should stop being supported – Endless May 23 '21 at 14:31