0

I am trying to pass an image dataURI as an input from a url link to the image. I understand to do this I must use canvas and convert it from there. However, since this is an 'async' method I can't produce a return.

    getLogo() {
    let image = new Image();
    let canvas = document.createElement('canvas');
    return new Promise((resolve) => {
      image.onload = () => {
        canvas.width = image.naturalWidth;
        canvas.height = image.naturalHeight;
        canvas.getContext('2d').drawImage(image, 0, 0);
        let uri = canvas.toDataURL('image/png');
        resolve(uri);
      };
      image.src = this.logo;
    });
  }

  getLogoURI() {
    this.getLogo().then((result) => {
      console.log(result); // the correct output writes here
      return result; // this returns undefined
    });
  }

I then call this from my class in which I need the URI, this is within a for loop.

let logo = tariff.getLogoURI();

I believe when calling getLogoURI(), this automatically treats it as a synchronous function and therefore doesn't return the right value, but I am unsure.

Dandydon
  • 103
  • 2
  • 11
  • Possible duplicate of [Return from a promise then()](https://stackoverflow.com/questions/34094806/return-from-a-promise-then) – Rehan Haider Jul 18 '18 at 07:05

1 Answers1

0

Let me explain current working of getLogoURI method

getLogoURI() {
  // when getLogoURI() is invoked, it calls getLogo()
  // getLogo() returns a promise,
  // whose then is being invoked with a success callback, which will be invoked on resolving of promise
  // then() function returns a promise which is not being returned by getLogoURI() method
  // so getLogoURI() method is not returning anything
  // if a function do not return any thing then undefined is returned by default
  // that's why you are receiving undefined
  this.getLogo().then((result) => {
    console.log(result); // the correct output writes here
    return result; // this returns undefined
  });
}

To solve this we can made few changes

getLogoURI() {
  // return promise being returned by then()
  return this.getLogo().then((result) => {
    console.log(result); // the correct output writes here
    return result; // this returns undefined
  });
}

now getLogoURI will return a promise and we can use it like this

getLogoURI().then(result => //use result here);

wait, this is what we already have done in getLogoURI, it means getLogoURI is just a useless wrapper you don't need to use it. The way you are trying to achieve it is impossible as these are async operations which can be done synchronously. I hope reading MDN's documentation of then will be helpful for you to understand it.

You can use async/await to make control flow easy and it pretty much looks like synchronous flow but it is purely asynchronous. Use it with caution it may have compatibility issues with some browsers. Using async/await your above code will look like this

async useLogoURI() {
  let logo = await this.getLogo();
  // use logo here
}
Rehan Haider
  • 893
  • 11
  • 26