So, I am implementing findOrCreate on my User schema which basically just has and array of profiles (each user can have multiple login strategies). You may take it as a given that a user is positively identified by having a profile with matching provider and id to the supplied profile we are calling findOrCreate with. The goal of findOrCreate is to identify the user that matches the supplied profile or create a new user using the supplied profile. This function has four return cases.
Now, I believe that the following code does this. My concern and reason for this question is that callback supplied to findOne does not consistently return. If there is an error while querying for the user, we return callback(...) and if we find the user, we return callback(...) however, if we need to create the user, we never explicitly return. Is there someway that I can return the result of the save? Is that even what I should be doing or is this correct the way I have it?
Code:
UserSchema.static('findOrCreate', function (profile, callback) {
this.findOne({ profiles: { $elemMatch: { provider: profile.provider, id: profile.id }}}, function(err, user) {
if (err)
return callback(err);
if (user)
return callback(null, user);
user = new User({
profiles: [profile]
});
user.save(function (err, user) {
if (err)
return callback(err);
return callback(null, user);
});
});
});
Just do user.save(callback); since your inline anonymous function there is essentially identical to what save already does with its callback. The return statements are purely flow-control mechanisms whose sole purpose is to avoid execution of subsequent code within this function and the actual return value itself is ignored entirely by the caller as is customary in asynchronous programming in node. You could code identical logic using if/else blocks instead of if/return guard clauses and never use the return keyword at all and still get this function behaving correctly.