Skip to content

Instantly share code, notes, and snippets.

@diegonetto
Last active August 29, 2015 14:03
Show Gist options
  • Save diegonetto/762c18a4a086a8dbb507 to your computer and use it in GitHub Desktop.
Save diegonetto/762c18a4a086a8dbb507 to your computer and use it in GitHub Desktop.
AngularJS ModelService paradigm for sharing data between controllers
// Quick and dirty example that illustrates the ModelService paradigm
// for sharing data models between multiple controllers.
//
// Once `UserService` is injected into a controller and `UserService.login()`
// returns successfully, any expressions data-bound to properties of the
// `UserService.model` object in the scope of other controllers should be properly updated.
//
// In this example, model mutation is controlled within the context of the
// service, so only calls to `UserService.login()` will update `UserService.model`.
// It would also make since to have the UserService API expose an `update()`
// function that wraps $ngResource and updates the data model accordingly.
// http-auth-interceptor - https://github.com/witoldsz/angular-http-auth
// is used to implement basic authentication.
angular.module('TestApp', ['ngResource', 'http-auth-interceptor'])
// I prefer using PUT's to update backend collections, so
// $save is overwritten to call create() or update() as needed
.factory('Resource', function ($resource) {
return function (url, params, methods) {
var defaults = {
create: { method: 'post' },
update: { method: 'put' }
};
methods = angular.extend(defaults, methods);
var resource = $resource(url, params, methods);
resource.prototype.$save = function() {
if (!this._id) {
return this.$create();
} else {
return this.$update();
}
};
return resource;
};
})
// Simple UserService which exposes an API that wraps RESTful routes
// and allows model data to be shared between controllers
.service('UserService', function (Resource, authService) {
var URL = 'http://api.example.com/';
var UserModel = { email: '', password: '', fullName: '', age: '' };
// UserResource will now contain get(), save(), query(), delete(),
// signup(), login(), and logout() methods.
var UserResource = Resource(URL + 'user/:id', { id: '@_id' }, {
signup: { method: 'post', url: URL + 'signup' },
login: { method: 'post', url: URL + 'login', withCredentials: true, ignoreAuthModule: true },
logout: { method: 'post', url: URL + 'logout', withCredentials: true }
});
// UserService contains our desired API
var UserService = {
// Expose User data model
model: UserModel,
// Custom login implementation since we're using
// http-auth-interceptor module
login: function (user, success, failure) {
UserResource.login(user, function(data) {
UserModel = user;
authService.loginConfirmed();
if (success) success(data);
}, function(error) {
if (failure) failure(error);
});
},
// delegates to ngResource
logout: UserResource.logout,
// delegates to ngResource
signup: UserResource.signup
};
// Expose the service API
// If we wanted all of the UserResource methods it would make sense
// to `return angular.extend(UserResource, UserService)` instead
return UserService;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment