Gerrit SG Gerrit SG - 4 months ago 28
Javascript Question

Best practices for waiting on the result of a function in Meteor?

I've got this function that involves uploading an image to Cloudinary, and then setting the component's state to be the resulting URL. Here's what it looks like:



loadFileFront: function(e) {
var imageFrontURL = window.webkitURL.createObjectURL(e.target.files[0]);
var imageFrontFile = e.target.files[0];
var returnedURL = '';
Cloudinary._upload_file(imageFrontFile, {}, function(err, res) {
if (err){
console.log(err);
return;
}
console.log(res.url);
});
this.setState({
imageFront: returnedURL,
imageFrontFile: imageFrontFile
})
},





(Ignore that top line with createObjectURL).
I've been doing a bunch of research into how best to structure this so that setState waits on the the upload to complete the the res.url to be returned, thus updating the state properly. When I console.log res.url, after a few seconds it shows up. However when I try to set returnedURL to res.url, there's no waiting and it just jumps ahead through the rest of the function.
What's the best way to wait on the result of the Cloudinary upload here? I've been reading about the async / await support in Meteor 1.3, but I've been having trouble figuring out how to configure this Cloudinary upload method in a Meteor method on the server. Any help is appreciated!

Answer

If I understand the problem correctly, then this should fix it. You want to do a fat arrow function on the callback so you can correctly pass (this), and won't have any issues calling this.setState. Also since the key and value of imageFrontFile are the same, you can use it as I typed it below. Hope that helps.

loadFileFront: function(e) {
    var imageFrontURL =  window.webkitURL.createObjectURL(e.target.files[0]);
    var imageFrontFile = e.target.files[0];
    var returnedURL = '';
    Cloudinary._upload_file(imageFrontFile, {}, (err, res) => {
        if (err){
            console.log(err);
            return;
        }
        this.setState({
            imageFront: res.url,
            imageFrontFile
        });
    });
},