Angular: Async Await- EventListener inside a promise

Viewed 529

I've been struggling since a day on this issue. I want to create this kind of situation:

<img [src]="userdp | async" />

in component.ts file I want to have this line only:

this.userdp = this._userService.getUserDp();

in the getUserDp(), here's the code:

async getUserDp() {
    return await
    this._http.get(APIvars.APIdomain+'/'+APIvars.GET_USER_DP,  { responseType: 'blob' }).toPromise().then( image => {
        if(image['type'] === 'application/json') {
          return null;
        }
        const reader = new FileReader();
        reader.addEventListener('load', () => {
           **return this._dom.bypassSecurityTrustResourceUrl(reader.result.toString());**
        });
        }, false);
        if (image) {
          reader.readAsDataURL(image);
        }
    });
  }

Promise is not waiting for the reader to load in EventListener, any immediate return statement gives the intended result, the line in bold is the main data to be returned.

Thanks

2 Answers

You can make your life easier -- and the lives of future readers of the code -- by creating a promise-returning FileReader method, getting out of the callback business in one place.

// return a promise that resolves on the 'load' event of FileReader
async function readAsDataURL(image) {
  const reader = new FileReader();
  return new Promise((resolve, reject) => {
    reader.addEventListener('load', () => {
      resolve(reader.result.toString());
    });
    // consider adding an error handler that calls reject
    reader.readAsDataURL(image);
  });
}

Now that the file handling code has been "promisified", it's easier to use...

async getUserDp() {
  // temp vars so we can read the code
  const url = APIvars.APIdomain+'/'+APIvars.GET_USER_DP;
  const options = { responseType: 'blob' };
  
  // await replaces .then() here
  const image = await this._http.get(url,  options).toPromise();
  
  // not sure whether this is right, just following OP logic here
  // bail if the image (result of the get()) is falsey or is of type json
  if (!image || image['type'] === 'application/json') return null;
  
  // simple to call to await file reading
  const readerResult = await readAsDataURL(image);
  return this._dom.bypassSecurityTrustResourceUrl(readerResult);
}  

Replace you promise to

    reader.onload = function (e) {
       
    }; 
Related