As of right now I have a beforeSave function that prevents duplicate emails from being saved shown below.
Parse.Cloud.beforeSave("Email", function(request, response) {
var query = new Parse.Query("Email");
// Gets the email key value (string) before object is saved
query.equalTo("address", request.object.get("address"));
// Checks to see if an object for that email already exists
query.first({
success: function(object) {
if (object) {
response.error("Email already Exists");
} else {
response.success();
}
},
error: function(error) {
response.error("Could not determine if this email exists");
}
});
});
Function that creates emails but if someone adds an email address to their project that we have saved before this will break the function and ultimately the chain of promises that this function exists in, at least in my understanding.
function createEmails(emails) {
var EmailsClass = Parse.Object.extend("Email");
var toSave = _.map(emails, function(emailAddress) {
var email = new EmailsClass();
email.set("address", emailAddress);
return email;
});
return Parse.Object.saveAll(toSave);
}
Hopefully somebody has a better answer than this, but it seems that the only way to avoid saving on beforeSave
is to respond with an error, and that flummoxes subsequent processing.
So, if attempting to create a duplicate is not an error from an application point of view, just a condition to be disallowed, then I think you must catch that before beforeSave
, by filtering the input for duplicates.
That's not so pretty when creating in bulk, but it would go something like this:
// answer a promise for an existing email object with address==email or a promise to save a new one
function fetchOrCreateEmail(emailAddress) {
var EmailsClass = Parse.Object.extend("Email");
var query = new Parse.Query(EmailsClass);
query.equalTo("address", emailAddress);
return query.first().then(function(object) {
if (!object) {
object = new EmailsClass();
object("address", emailAddress);
return object.save();
} else {
return Parse.Promise.as(object);
}
});
}
// create Email objects with a given array of addresses, creating
// objects only for unique addresses
function createEmails(emails) {
var toSave = _.map(emails, fetchOrCreateEmail);
return Parse.Promise.when(toSave);
}
With this fetchOrCreateEmail
function, you can create in batch as shown, or create a single like this:
fetchOrCreateEmail(emailAddress);
If you use these for all creation of Email objects, you'll no longer need (or want) the beforeSave
hook for that class. I'd like to find out if there's a better solution than this one, but I think that's the best that can be done at present.