JDS JDS - 4 years ago 131
Javascript Question

How to correctly implement a javascript callback

I am trying to implement a javascript callback in my function. What is the proper way to accomplish this?

This function is called and will call the createImage function.

function getImage(reportId) {
console.log("In getImage");
var imageData = createImage(returnImage);
};


I then see my the message "In createImage done" logged. However I do not see an other console.log messages occur. I don't see any of the messages in the callback method, nor do I see "All done done done" message.

function createImage(callback) {
kendo.drawing.drawDOM($("#map"))
.then(function (group) {
return kendo.drawing.exportImage(group);
})
.done(function (data, callback) {
console.log("In createImage done");
$("#staticImage").attr("src", data);
callback();
console.log("All done done done");
});
};


This is the callback function...

function returnImage(reportId, data)
{
console.log("In returnImage");
console.log("reportId = " + reportId);
console.log("data = " + data);
window.parent.buildSlideModel(reportId, data);
}

Answer Source

A couple of things to note here, the primary problem is that you are redefining callback in your done handler, and it is undefined. When you try to call it you get an error, but that error is consumed by the promise. What you need to do is something like the following:

function getImage(reportId) {
    console.log("In getImage");
    var imageData = createImage(reportId, returnImage); // pass in reportId
}

function createImage(reportId, callback) { // accept reportId and callback
    kendo.drawing.drawDOM($("#map"))
    .then(function (group) {
        return kendo.drawing.exportImage(group);
    })
    .done(function (data) { // Don't redefine callback
        console.log("In createImage done");
        $("#staticImage").attr("src", data);
        callback(reportId, data); // pass reportId and data to callback
        console.log("All done done done");
    });
}

function returnImage(reportId, data) {
    console.log("In returnImage");
    console.log("reportId = " + reportId);
    console.log("data = " + data);
    window.parent.buildSlideModel(reportId, data);
}

Some things to point out here:

  • You need to pass reportId through to createImage in order to be able to pass it to the callback.
  • You should not redefine callback in the done function handler

I would recommend avoiding using callbacks altogether. Something like the following will work:

function getImage(reportId) {
    console.log("In getImage");
    return createImage()
        .then(function(data) { // use a chained-then
            console.log("Image created");
            $("#staticImage").attr("src", data);

            returnImage(reportId, data); // call to returnImage

            return data;
        });
}

function createImage() {
    return kendo.drawing.drawDOM($("#map")) // return the promise
        .then(function (group) {
            return kendo.drawing.exportImage(group);
        });
}

function returnImage(reportId, data) {
    console.log("In returnImage");
    console.log("reportId = " + reportId);
    console.log("data = " + data);
    return window.parent.buildSlideModel(reportId, data);
}

I'm not 100% sure on what your needs are, since you name a function returnImage, but it appears to be making a call to window.parent.buildSlideModel and not actually returning anything. If that is indeed true, the above code will still accomplish what you need. If you name a function getImage then you might want that function to actually return the image data (or a promise of the data). I have done that for you in the above code.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download