pablobaldez
pablobaldez

Reputation: 924

Parse: using httpRequest to load image

I'm trying to load an image using Parse.Cloud.httpRequest promise inside of one beforeSave trigger, but apparently this promisse is not called. The error callback is called, but the error message is always empty.

Is possible do it into a beforesave trigger? Or maybe it's happening because of that i'm doing this inside of foreach?

The message "pablo# after load imageUrl" don't appears in Parses log, and the message "error when save user picture>>>" appears, but the error.text is empty

Parse.Cloud.beforeSave(Parse.User, function(request, response) {
    Parse.Cloud.useMasterKey(); 
    response.success();
    var found = false;      
    console.log(request.object.dirtyKeys());
    for (dirtyKey in request.object.dirtyKeys()) {

        if (request.object.dirtyKeys()[dirtyKey] === "imageurl") {
            found = true;

            Parse.Cloud.httpRequest({ 
                url: request.object.get("imageurl") 
            }).then(function(response) {
                console.log("pablo# after load imageUrl");
                var image = new Image();
                return image.setData(response.buffer);
            }).then(function(image) {
                return image.data();
            }).then(function(buffer) {
                var base64 = buffer.toString("base64");
                var fileTitle = request.object.id + ".png";
                console.log(fileTitle);
                var file = new Parse.File(String(fileTitle), { base64: base64 });
                return file.save();
            }).then(function(file) {            
                request.object.set("profileImage", file);
                console.log('success');

                response.success();                                            
            }, function(error) {
                console.error(error);
                response.error("error when save user picture>>> " + error.text);
            });                     
        }
    }

    if(!found){
        response.success(); 
    }   
});

Upvotes: 0

Views: 418

Answers (1)

danh
danh

Reputation: 62676

This is all doable with just a few improvements to the code: (1) don't call success() straight away or nothing at all will happen, (2) no need to loop dirty keys, since we're just checking for existence of one of them, (3) your code assumes that image.setData() returns a promise fulfilled by the image data: the docs are unclear about this but imply otherwise, (4) finally, let's factor the image stuff into a single, promise returning function so its easier to see what's happening...

Parse.Cloud.beforeSave(Parse.User, function(request, response) {
    fetchAndSaveUserImage(request.object).then(function() {
        response.success();
    }, function(error) {
        response.error(error);
    });
}

function fetchAndSaveUserImage(user) {
    if (user.dirtyKeys().indexOf("imageurl") == -1) { return false; }

    var image = new Image(); // more like docs, so we have the image in any block below
    var params = { url: request.object.get("imageurl") };
    return Parse.Cloud.httpRequest(params).then(function(response) {
        console.log("pablo# after load imageUrl");
        return image.setData(response.buffer);
    }).then(function() {
        return image.data();  // this is likely the same as response.buffer, but the docs do it, so just to be certain...
    }).then(function(buffer) {
        var base64 = buffer.toString("base64");
        var fileTitle = user.id + ".png";
        console.log(fileTitle);
        var file = new Parse.File(String(fileTitle), { base64: base64 });
        return file.save();
    }).then(function(file) {            
        request.object.set("profileImage", file);
        return true;
    });
}

Incidentally, I omitted useMasterKey since I saw nothing in the code needing more permission than what's already assumed in beforeSave of a User.

Upvotes: 2

Related Questions