2

I need to check the original object on before save to see what value has changed. currently i have this:

Parse.Cloud.beforeSave("Stats", function(request, response) {
if (!request.object.isNew()){
        var query = new Parse.Query("Stats");
        query.get(request.object.id, { 
            success: function(oldObject) {
            alert('OLD:' + oldObject.get("Score") + "new:" + request.object.get("Score"));
                /*Do My Stuff Here*/
                response.success(); 
            },
            error: function(oldObject, error) {
                response.error(error.message);
            }
        });
    }else{
        response.success();
    }

});

The problem is that oldObject is equal to request.object.

Also the alert result is this: OLD:10 new:10, but the real old score was 5. Also according to the before save input log the original is really 5.

Any ideia what i am doing wrong?

Edit: Here is the before save log.

before_save triggered for Stats as master:
Input: {"original":{"achievements":[],"Score":"100"updatedAt":"2015-11-02T10:09:24.170Z"},"update":{"Score":"110"}}
Result: Update changed to {"Score":"110"}

Edit2: Is there any way to get the dirty value?

console.log("dirty: "+ request.object.dirty("score"));
I2015-11-03T14:23:12.198Z]dirty: true
rob180
  • 901
  • 1
  • 9
  • 29
  • Did you check the to see if your Score field is dirty like `request.object.dirty("Score")` ? – Mo Nazemi Nov 02 '15 at 11:23
  • Both `request.object.dirtyKeys` and `request.object.dirty("Score")` return `undefined` – rob180 Nov 02 '15 at 11:58
  • Something must be wrong because if you are updating fields, you should see them flagged as dirty. Btw how does Javascript `alert` function work on Cloud ?? – Mo Nazemi Nov 02 '15 at 12:43
  • @MoNazemi [this](http://s2.postimg.org/q74o9gd15/Screen_Shot_2015_11_02_at_12_52_44.png) is how `alert` looks like – rob180 Nov 02 '15 at 12:55
  • If there are no dirty fields your request is not going to update anything, can you show what your update request looks like and how you are doing it ? – Mo Nazemi Nov 03 '15 at 11:46
  • @MoNazemi added the `before save` log. – rob180 Nov 03 '15 at 12:36
  • Have you tried calling `request.object.dirty("Score")` *before* the query? – natario Nov 03 '15 at 12:43
  • `request.object.dirty("score")` returns `true`. But how do i get the dirt `dirty` value? – rob180 Nov 03 '15 at 14:30
  • My guess is that querying for that object somehow updates all "instances" of that object in the current scope, and that's way dirty() works only if called *before*. As to how to get the old score, I don't know. You could create another field, "oldScore", and mantain it. – natario Nov 03 '15 at 16:26

1 Answers1

5

The official way to know if a field was modified is to call dirty().

My guess is that querying for that particular object somehow updates all "instances" of that object in the current scope, and that's way dirty() works only if called before the query.

An option to get both the old and the new value is to mantain it in a separate field. For example, from your client you could call (pseudocoding, but you get the point):

// OldScore here is 0
statObject.put("Score") = 100;
statObject.saveInBackground();

Then in Cloud Code:

Parse.Cloud.beforeSave("Stats", function(request, response) {

    var stat = request.object;
    if (!stat.isNew()){
        if (stat.dirty("Score")) {
            var newValue = stat.get("Score") // 100
            var oldValue = stat.get("OldScore") // 0

            // Do other stuff here

            stat.put("OldScore", newValue);
            response.success();

        } else {
            response.success();
        }
    } else {
        response.success();
    }
});

However the issue you are describing is somewhat strange. Maybe you could try with the fetch() command; it should return the old value. However it will invalidate every other dirty field.

natario
  • 24,954
  • 17
  • 88
  • 158
  • I did't wanted to duplicate the fields, and since the `before save` log has the original value i was wondering if there was any way to get it directly. If there no other way to achieve this i will accept your answer as correct. – rob180 Nov 03 '15 at 17:06
  • There is no API to get it directly, see the [answer here](https://parse.com/questions/cloudcode-haschanged-and-previous), but other guys here on SO used your exact method and it worked, see [here](http://stackoverflow.com/questions/25082262/parse-cloudcode-beforesave-obtain-pre-updated-object) for example. I don't know why it wouldn't work with you, maybe something changed in the SDK lately. – natario Nov 03 '15 at 17:13
  • I got my code from that post. Also, since that code did not work anymore i was wondering that was changed in any way. – rob180 Nov 03 '15 at 17:24