0

I'm saving some objects into tables on my Parse Data. But I need to add a constraint or make sure that the data i'm trying to insert is unique. I'm using something like the following code. But i want to guarantee that the eventId (that I'm getting from facebook API) is unique in my tables, so i don't have any redundant information. What is the best way to make it work?

var Event = Parse.Object.extend("Event");
var event = new Event();
event.set("eventId", id);
event.set("eventName", name);

event.save(null, {
  success: function(event) {
     console.log('New object created with objectId: ' + event.eventId);
  },
  error: function(event, error) {
     console.log('Failed to create new object, with error code: ' + error.message);
  }
});

Update:

I'm calling it inside a httpRequest. The following is pretty much what I have and I cant figure out just how to call a beforeSave inside it.

Parse.Cloud.define("hello", function(request, response) {

    var query = new Parse.Query("Location");
    query.find({
        success: function(results) {
            console.log(results);
        var totalResults = results.length;
        var completedResults = 0;
        var completion = function() {
          response.success("Finished");
        };

            for (var i = 0; i < totalResults; ++i){

            locationId = results[i].get("locationFbId");

            Parse.Cloud.httpRequest({
              url: 'https://graph.facebook.com/v2.2/'+locationId+'/events?access_token='+accessToken,
              success: function(httpResponse) {
                console.log(httpResponse.data);

                console.log("dsa"+locationId);
                for (var key in httpResponse.data) {
                  var obj = httpResponse.data[key];
                  for (var prop in obj) {
                    var eventObj = obj[prop];
                    if (typeof(eventObj) === 'object' && eventObj.hasOwnProperty("id")) {
                      var FbEvent = Parse.Object.extend("FbEvent");
                      var fbEvent = new FbEvent();
                      fbEvent.set("startDate",eventObj["start_time"]);
                      fbEvent.set("locationFbId", locationId);
                      fbEvent.set("fbEventId", eventObj["id"]);
                      fbEvent.set("fbEventName", eventObj["name"]);

                      Parse.Cloud.beforeSave("FbEvent", function(request, response) { 
                        var query = new Parse.Query("FbEvent");
                        query.equalTo("fbEventId", request.params.fbEventId);
                        query.count({
                          success: function(number) {
                            if(number>0){
                              response.error("Event not unique");
                            } else {
                              response.success();
                            }
                          },
                          error: function(error) {
                            response.error(error);
                          }
                        });   
                      });                 
                    }
                  }
                }

                completedResults++;
                if (completedResults == totalResults) {
                  completion();
                }
              },
              error:function(httpResponse){
                completedResults++;
                if (completedResults == totalResults)
                  response.error("Failed to login");
              }
            });
        }
        },
        error: function() {
            response.error("Failed on getting locationId");
        }
    });
});
adolfosrs
  • 9,286
  • 5
  • 39
  • 67

1 Answers1

2

So this is occurring in Cloud Code correct? (Im assuming since this is Javascript)

What you could do is create a function that occurs before each "Event" object is saved and run a query to make sure that the event is unique (query based off of "eventId" key, not objectId since the id comes from Facebook). If the event is unique, return response.success(), otherwise return response.error("Event not unique")

EX:

Parse.Cloud.beforeSave("Event", function(request, response) {
                if(request.object.dirty("eventId")){ 
                    var query = var new Parse.Query("Event");
                    query.equalTo("eventId", request.object.eventId);
                    query.count({
                        success: function(number) {
                            if(number>0){
                                response.error("Event not unique");
                            } else {
                                response.success();
                            }
                        },
                        error: function(error) {
                            response.error(error);
                        }
                    });  
                } else {
                    response.success();
                } 
});  
Parse.Cloud.define("hello", function(request, response) {
    var query = new Parse.Query("Location");
    query.find({
        success: function(results) {
            console.log(results);
        var totalResults = results.length;
        var completedResults = 0;
        var completion = function() {
          response.success("Finished");
        };
            for (var i = 0; i < totalResults; ++i){
            locationId = results[i].get("locationFbId");
            Parse.Cloud.httpRequest({
              url: 'https://graph.facebook.com/v2.2/'+locationId+'/events?access_token='+accessToken,
              success: function(httpResponse) {
                console.log(httpResponse.data);
                console.log("dsa"+locationId);
                for (var key in httpResponse.data) {
                  var obj = httpResponse.data[key];
                  for (var prop in obj) {
                    var eventObj = obj[prop];
                    if (typeof(eventObj) === 'object' && eventObj.hasOwnProperty("id")) {
                      var FbEvent = Parse.Object.extend("FbEvent");
                      var fbEvent = new FbEvent();
                      fbEvent.set("startDate",eventObj["start_time"]);
                      fbEvent.set("locationFbId", locationId);
                      fbEvent.set("fbEventId", eventObj["id"]);
                      fbEvent.set("fbEventName", eventObj["name"]);
                      // Our beforeSave function is automatically called here when we save it (this will happen every time we save, so we could even upgrade our method as shown in its definition above)
                      fbEvent.save(null, {
                          success: function(event) {
                               console.log('New object created with objectId: ' + event.eventId);
                          },
                          error: function(event, error) {
                              console.log('Failed to create new object, with error code: ' + error.message);
                          }            
                      });                 
                    }
                  }
                }
                completedResults++;
                if (completedResults == totalResults) {
                  completion();
                }
              },
              error:function(httpResponse){
                completedResults++;
                if (completedResults == totalResults)
                  response.error("Failed to login");
              }
            });
        }
        },
        error: function() {
            response.error("Failed on getting locationId");
        }
    });
});

This can also be accomplished before ever calling the save by querying and only saving if the query returns with a number == 0.

Summary: For those joining later, what we are doing here is checking to see if an object is unique (this time based on key eventId, but we could use any key) by overriding Parse's beforeSave function. This does mean that when we save our objects (for the first time) we need to be extra sure we have logic to handle the error that the object is not unique. Otherwise this could break the user experience (you should have error handling that doesn't break the user experience anyway though).

Patrick Bradshaw
  • 536
  • 4
  • 10
  • Yeah. This is an alternative. But i wanted something more performance friendly. :/ – adolfosrs Jan 03 '15 at 15:11
  • Also. Will it save the data after returning the response.success? Or will I need to call my event.save either way? – adolfosrs Jan 03 '15 at 15:35
  • I'm calling it after instantiate my Event object. And this is returning this wierd thing "Error: beforeSave for FbEvent has already been registered". :/ Any idea? – adolfosrs Jan 03 '15 at 15:42
  • 1
    For Parse, you don't have to explicitly call before save. It is called every time an object is saved normally, so its not an extra call, just something for that call to do. You shouldn't put the method definition inside your existing one, but rather place the code that I posted as a new function outside of the "hello" definition. response.success will save the object, response.error will cause the object to not save. I'll update my answer as well to show you what I mean with code placement – Patrick Bradshaw Jan 03 '15 at 16:55
  • Just to let you know, I also found a typo in my last answer, instead of request.params.eventId, it should have been request.object.eventId. Sorry! – Patrick Bradshaw Jan 03 '15 at 17:10