0

This is not going to be the best parse.com question out there, but it's the first time I write something in javascript and I can't figure out what's wrong.

In my db I have ParsePosts, ParseUsers and ParseComments. When I delete a post, I want the following to be done:

  • Task 1: find the user who wrote the post, and decrement his "posts" counter;
  • Task 2: delete all ParseComments that were related to the post to-be-deleted;
  • Task 3: find user who "liked" the post, and decrement their "likes" counter.

I'm trying as follows (renaming some variables so there might be typos):

Parse.Cloud.beforeDelete("ParsePost", function(request,response) {
  var post = request.object;
  var user = post.get("author");
  user.increment("posts",-1);
  user.save().then(function(success) {

    var query = new Parse.Query("ParseComment");
    query.equalTo("post",post);
    return query.find();

  }).then(function(comments) {
    for (var i = 0; i < comments.length; i++) {
      var comment = comments[i];
      comment.destroy();
    }

    var query2 = new Parse.Query("ParseUser");
    query2.equalTo("postsLiked",post); //"postsLiked" is a relation field
    return query2.find();

  }).then(function(users) {
    for (var i = 0; i < users.length; i++) {
      var u = users[i];
      u.increment("postsLikedCount",-1);
      u.save();
    }
    response.success();
  });
});

However, deleting fails with the message: Result: success/error was not called. I have no idea why.

The way I dealt with promises, as far as I understood (not much), should call the next then() even if there's an error in one of the steps before. In other words, the three tasks are not really consequential - I'd like the function to:

  • try to accomplish each task;
  • call success() no matter the output of the tasks: I want the post to be deleted even if, say, comments.length == 0.

How should I accomplish that, and why my function is not reaching response.success()?

As a side note, I haven't even found a way to debug - I use parse deploy and then look at the logs section in parse.com, but I can't manage to write anything into it. Namely, console.log() gives no output.

1 Answer 1

1

One of your promises is throwing an error, and you do not have any .then()'s that catch that error. .then() either takes 1 or 2 arguments, both of which are functions. If there is only 1, it takes the resolved value of a promise. If there are 2, the second one takes the rejected value of a promise. One of your promises is being rejected, but the promise is never being caught. Add this to the end of your chain:

.then( function(){},
        function(error)
        {
             response.error("There was an error: " + error.message);
        }
    );

Rejected promises skip any link in the promise chain that does not contain an error handler, so having this one link at the end will catch any error from earlier links. Even if you call response.success() and don't return a promise, the success function of the next chain will be called. You just won't be passing anything in to the variable, so it'll be null/undefined

Edit - Looking at your code, I bet it's going to be an issue pretty early on. You never fetched the user, so it's just an empty object with nothing but an object id right now.

Edit2 - Also, query.find() only returns the first 1000 results. If you want to do something to every single object, you should be using query.each().

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you very much. I'm going to answer randomly - edit1: I'm never calling get() on the user, so that shouldn't be an issue, right? edit2: that is true, I had not thought about it. body: I see. Would it be so bad to call response.success() rather than response.error()? If you don't return success from a beforeDelete call the objects does not get deleted, of course, but I'd like my Post to be deleted even if there's an uncaught-something behind.
I managed to solve the issue myself and rewrote most of my cloud code. Thank you for shedding some light on parse promises.
There's one thing I'm not 100% sure of. In the above code (mine), for example, at for (var i = 0; i < comments.length; i++): would this break if the query returns no comments? I mean, in java, to make it error safe, I would have to check for comments != null. What about javascript? Would the chain break (and go to the very last error function), or continue with no errors at all?
It shouldn't break/ comments.length will be an empty array with length 0, so your for loop will fail on the first conditional check and never execute anything within. for edit1, you were trying to increment a field, but since you didn't have the value, you don't know what to increment. My guess is that that has something to do with your error. You were probably failing on the user.save().I'd put the fetch in there just to be safe. edit2 - if you want, but for testing purposes, I'd do response.error() while you figure out your error, and maybe do response.success() in production.
Although, it would be much more proper to include error handling in your client side code, and be able to return response.error() and show an appropriate error message. That's definitely the best route to take, though it may be more difficult to implement.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.