Sowmyan Soman
Sowmyan Soman

Reputation: 923

access blob value outside of canvas.ToBlob() async function

I'm working with HTMLCanvas element that return the blob object outside of the async toBlob() function. This function doesn't return an output value, so I'm trying to declare a variable outside and access it through the command.

How I can use JS Promise for this scenario?

var myblob;
            canvas.toBlob(function(blob) {                         
                              myblob = blob;
                              console.log("inside " + myblob); // getting value after the console outside
                           })
 console.log( "outside " + myblob); // getting undefined   

Upvotes: 29

Views: 21617

Answers (4)

rofrol
rofrol

Reputation: 15266

Typescript version:

function toBlob(canvas: HTMLCanvasElement): Promise<Blob> {
  return new Promise((resolve) => {
    canvas.toBlob(blob => {
      if (blob) resolve(blob);
    });
  });
}

Upvotes: 5

Guillermo Perez
Guillermo Perez

Reputation: 649

I HAVE ANOTHER IDEA... similar to the one marked as best idea... the problem with then is that you have to be inside the block in order to pick up the result from the promise. Now Javascript supports await similar to c#, this is good because you can run the function and wait until is resolved, then you get the result to a variable not attached to any function, example:

/* basically we create a function that receives a canvas called mycanvas, then we tell the function to return a new Promise, this promise is "resolved" inside the .toBlob method which by default provides a Blob parameter. */

function getCanvasBlob(mycanvas) {
  return new Promise(function(resolve, reject) {
    mycanvas.toBlob((blob) => {
      resolve(blob)
    })
  })
}

var myblob;

try{
  myblob = await getCanvasBlob(CANVAS_FROM_SOMEWHERE);
}
catch (error){
  console.log(error);
}

/* There's no need to use try/catch, you could use it just like this */

var myblob = await getCanvasBlob(CANVAS_FROM_SOMEWHERE);

As the method is async, then() is not executed or called until the promise is resolved, anything outside this method will not be notified of changes until is too late... The advantage here is that our javascript will not continue until the promise has been fully resolved.

ADDITIONAL INFO: If you call await, the method from where you are calling this function must be marked as async, otherwise you will see an error... lets say for example this is called inside a click of a button:

/* OBVIOUSLY this will throw an error because I don't have a real canvas...*/

$( document ).ready(function() {
    
    $('#mybutton').bind('click', async function(){
    
      //...more code...
      //...more code... until...
      
      var CANVAS_FROM_SOMEWHERE;
      
      var myblob = await getCanvasBlob(CANVAS_FROM_SOMEWHERE);
    
    });
    
});

function getCanvasBlob(mycanvas) {
  return new Promise(function(resolve, reject) {
    mycanvas.toBlob((blob) => {
      resolve(blob)
    })
  })
}

   

    
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="mybutton">process my canvas!</button>

Upvotes: 4

KeyKi
KeyKi

Reputation: 3233

const blob = await new Promise(resolve => canvasElem.toBlob(resolve));

Upvotes: 84

guest271314
guest271314

Reputation: 1

You can use Promise constructor, pass Blob instance to resolve(), access Promise value at .then()

function getCanvasBlob(canvas) {
  return new Promise(function(resolve, reject) {
    canvas.toBlob(function(blob) {
      resolve(blob)
    })
  })
}

var canvasBlob = getCanvasBlob(canvas);

canvasBlob.then(function(blob) {
  // do stuff with blob
}, function(err) {
  console.log(err)
});

Upvotes: 28

Related Questions