amit
amit

Reputation: 1413

Parse beforeSave() cloud code function not working

I have added a beforeSave() Parse cloud function defined that is not working correctly.

Here is the background: I have a class called UserRewards that has a column called user of type ParseRelation. It consists of exactly 1 relation which has a single object of type ParseUser. I have a new column pUser that I would like to set in this function. It looks up the user relation, finds the ParseUser in it, and sets pUser to that user.

Here's the code I have

Parse.Cloud.beforeSave("UserRewards", function(request, response) {
    var relation = request.object.relation("user");
    relation.query().find({
            success: function(list) {
                console.log("looked up relation");
                if (list.length > 0) {
                    var pUser = list[0];
                    request.object.set("pUser", pUser);
                    console.log("updated pUser");
                }
            },
                error: function(error) {
                console.error("unable to lookup relation");
            }
    });
    response.success();

});

When I update a UserRewards row, this function is being called. But it does nothing - no console or error logs whatsoever.

Any ideas?

Upvotes: 1

Views: 2014

Answers (1)

danh
danh

Reputation: 62686

Your function runs response.success() before the query completes, thereby canceling it. Try...

Parse.Cloud.beforeSave("UserRewards", function(request, response) {
    var relation = request.object.relation("user");
    relation.query().find({
            success: function(list) {
                console.log("looked up relation");
                if (list.length > 0) {
                    var pUser = list[0];
                    request.object.set("pUser", pUser);
                    console.log("updated pUser");
                }
                response.success();
            },
                error: function(error) {
                console.error("unable to lookup relation");
                response.error(error);
            }
    });
});

Or, easier to look at with promises...

Parse.Cloud.beforeSave("UserRewards", function(request, response) {
    var relation = request.object.relation("user");
    relation.query().find().then(function(list) {
        console.log("looked up relation");
        if (list.length > 0) {
            var pUser = list[0];
            request.object.set("pUser", pUser);
            console.log("updated pUser");
        }
        response.success();
    }, function(error) {
        console.error("unable to lookup relation");
        response.error(error);
    });
});

EDIT I think I understand the followup question as asking to synch the pointer attribute with the relation attribute, assuming only one of them is set before the save. This can be done by detecting that the relation is empty. If it is, do one more asynch step to fetch the pointer...

Parse.Cloud.beforeSave("UserRewards", function(request, response) {
    var relation = request.object.relation("user");
    relation.query().find().then(function(list) {
        console.log("looked up relation");
        if (list.length > 0) {
            var pUser = list[0];
            request.object.set("pUser", pUser);
            console.log("updated pUser");
            return Parse.Promise.as();  // we're done, this will pass nothing to the next step
        } else {  // the relation is empty, so the user pointer must be set
            var pointer = request.object.get("pUser");
            return pointer.fetch();    // this will pass the pUser to the next step
        }
    }).then(function(pUser) {
        if (pUser) {
            // must have found an empty relation in the last step.  add the user pointer to it
            request.object.relation.add(pUser);
        }
        response.success();
    }, function(error) {
        console.error("unable to lookup relation");
        response.error(error);
    });
});

(Note the code is untested).

Upvotes: 2

Related Questions