bbking7
bbking7

Reputation: 85

How to implement callback function in this case

I'm new to JS callback functions. Looked at a few examples but can't work it out for this case.

I want to assign the width and height variables to the dimensions array. Width and height are returned by .load() function, hence callback is required.

  var size; // undefined var
var dimensions = [];

function getMeta(url){

  $('<img/>').attr('src', url).load(function(){
     size = {w:this.width, h:this.height};
     //myDelayedFunction();
     //var imageDimendions = [];
     var imageDimendions = myDelayedFunction();        

     var width = imageDimendions[0];
     var height = imageDimendions[1];

     dimensions.push(width);
     dimensions.push(height);
     //alert(width); //works fine here
    //alert(height); //works fine here


  });

  alert(dimensions); //alerts "undefined"
  return dimensions;
}

function myDelayedFunction(){
    //var imageDimensions = array();
    var width  = size.w;
    var height = size.h;
    var imageDimensions = [];
    imageDimensions.push(width);
    imageDimensions.push(height);
    //alert(imageDimensions);
    return imageDimensions;

}

var imageDimensions = getMeta(imageURL);
var imageWidth = imageDimensions[0];
var imageHeight = imageDimensions[1];

Upvotes: 0

Views: 75

Answers (3)

yosiweinreb
yosiweinreb

Reputation: 485

The load argument function is the callback, and it is being executed asynchronously.

You'll need to add a callback argument function to the getMeta, and execute it on the callback function that load() will execute.

function getMeta(url, callback){

  $('<img/>').attr('src', url).load(function(){
     //{{2}}
     size = {w:this.width, h:this.height};

     dimensions.push(size.w);
     dimensions.push(size.h);
     callback(dimensions)


  });



}

getMeta(imageURL,function(imageDimensions){
    var imageWidth = imageDimensions[0];
    var imageHeight = imageDimensions[1];
    alert(dimensions) // works!
    // {{3}}
    runProgram()
});
//{{1}}
alert(dimensions) // undefined


function runProgram(){
   alert(dimensions) //works!
   //continue here...
}

Javascript is a single thread language, so code that runs at {{1}} will always run before {{2}} and {{3}} - that is because of the load() function which is async - eg: will run only when the image was loaded.

So when you say "Outside getMeta" you basically saying - before the image loaded

And that's why in javascript, we use callbacks when we want to "return" something that requires asynchronous manner - such as image loading.

Upvotes: 1

Zohaib Ijaz
Zohaib Ijaz

Reputation: 22875

As you said, callback returns width and height then use these two arguments in callback like

.load(function(width, height){
     size = {w:width, h:height};
});

or it can be

.load(function(dimensions){
     size = {w: dimensions.width, h: dimensions.height};
});

Upvotes: 0

Guffa
Guffa

Reputation: 700192

Using a callback to just assign the result doesn't help you. The purpose of the callback is to wait until the result is available, so you have to use the result in the callback.

Just send the width and height as parameters to the callback. This is all the code that you need for that:

function getMeta(url, callback){
  $('<img/>').attr('src', url).load(function(){
     callback(this.width, this.height);
  });
}

getMeta(imageURL, function(imageWidth, imageHeight) {
  // use the image size
});

Upvotes: 0

Related Questions