I've written 3 factories as a part of a sign up process in AngularJS and Firebase. After completing them, I thought to myself, would any of these fit better as a service instead of a factory? From my research it's a bit fuzzy when it comes to choosing whether to create a service or a factory. If so, why would they fit better as a service? How can I tell when to create a service and when to create a factory?
I've documented the methods
to explain what they do, and the ones that lack a documentation explains themselves in the key
name.
forumApp.factory('fbRef', ['$firebase', '$firebaseAuth', function($firebase, $firebaseAuth) {
return {
getReference: function(path) {
return path ? new Firebase('https://mydbname.firebaseio.com/' + path) : new Firebase('https://forum-app.firebaseio.com');
},
getSyncedReference: function(path) {
return $firebase(this.getReference(path));
},
getAuthObj: function(path) {
return $firebaseAuth(this.getReference(path));
}
};
}]);
forumApp.factory('validation', [function() {
/**
* Validate user input before any database entries
*
* @param String $input
* Unvalidated input.
*
* @return Boolean
* True -> Input passed validation.
* False -> Input faulty, return error
*/
return {
validateSignup: function(user) {
for (var info in user) {
if (user[info] === '') {
return 'All fields must be filled in';
}
}
if (user.age > 99) {
return 'Sorry grandma, you are too old for this forum';
}
else if (isNaN(user.age)) {
return 'Age only allows digits';
}
else if (user.email === undefined) {
return 'Invalid email format';
}
else if (user.password != user.confirmedPassword) {
return 'The passwords do not match';
}
else if (user.isTermsAccepted === false) {
return 'You must accept the terms and service agreement';
}
}
}
}]);
forumApp.factory('dbEntry', ['$firebase', 'fbRef', '$location', function($firebase, fbRef, $location) {
return {
/**
* Insert user details into Firebase
*
* @param Object(s) user, userData
* User details, user ID
*
* @return Boolean
* True -> Successful database entry
* False -> Unsuccessful database entry
*/
insertUserDetails: function(user, userData) {
return fbRef.getSyncedReference(userData.uid).$set({
firstname: user.firstname,
lastname: user.lastname,
age: user.age,
country: user.country,
displayName: user.displayName,
email: user.email
}).then(function() {
return true;
}, function(error) {
return false;
});
},
/**
* Create a new user account in Firebase
*
* @param Object user
* User details
*
* @return String
* If error -> error message
* If successful:
* -> store user details
* -> change location hash to homepage
*/
createNewUser: function(user) {
var self = this;
return fbRef.getAuthObj().$createUser({
email: user.email,
password: user.password
}).then(function(userData) {
var isDetailsStored = self.insertUserDetails(user, userData);
isDetailsStored ? $location.path('/home') : this.removeUser(user);
}).catch(function(error) {
switch (error.code) {
case 'EMAIL_TAKEN':
return 'Email already registered';
default:
return 'Connection error - try again later';
}
});
},
/**
* Remove the newly-created user if
* details entry failed to force
* the user to sign up again
*
* @param Object user
* User details
*
* @return Boolean
* True -> User removal successful
* False -> User removal unsuccessful
*/
removeUser: function(user) {
return fbRef.getAuthObj().$removeUser({
email: user.email,
password: user.password
}).then(function() {
return true;
}).catch(function(error) {
return false;
});
}
};
}]);