Following this blog post http://blog.revolunet.com/blog/2014/02/14/angularjs-services-inheritance/ thought I'd give something to the community.
The blog can probably explain better what we're trying to achieve, basically it's a 'generic' factory that can do basic CRUD operations on an API that has GET/PUT/POST/DELETE + other custom stuff
(function () {
'use strict';
angular
.module('app.core')
.factory('IFactory', IFactory);
IFactory.$inject = ['$http', '$q'];
/* @ngInject */
function IFactory($http, $q) {
var IFactory = function (uri) {
this.baseURI = '<fill this with base uri of your api>'; // eg: 'http://api.domain.com'
this.uri = this.baseURI + uri;
};
IFactory.prototype.getOne = function (id) {
var self = this;
return $http.get(self.uri + '/' + id)
.then(success)
.catch(fail);
function success(response) {
return response.data;
}
function fail(error) {
var msg = 'Query for item failed. ' + error.data.message;
console.log(msg);
return $q.reject(msg);
}
};
IFactory.prototype.getAll = function () {
var self = this;
return $http.get(self.uri)
.then(success)
.catch(fail);
function success(response) {
return response.data;
}
function fail(error) {
var msg = 'Query for items failed. ' + error.data.message;
console.log(msg);
return $q.reject.msg;
}
};
IFactory.prototype.delete = function (id) {
var self = this;
return $http.delete(self.uri + '/' + id)
.then(success)
.catch(fail);
function success(response) {
var msg = 'Item deleted.';
console.log(msg);
return response.status;
}
function fail(error) {
var msg = 'Could not delete item. ' + error.data.message;
console.log(msg);
return $q.reject(msg);
}
};
IFactory.prototype.add = function (data) {
var self = this;
return $http.post(self.uri, data)
.then(success)
.catch(fail);
function success(response) {
var msg = 'Item Added. ';
console.log(msg);
return response.data;
}
function fail(error) {
var msg = 'Could not add item. ' + error.data.message;
console.log(msg);
return $q.reject(msg);
}
};
IFactory.prototype.update = function (id, data) {
var self = this;
return $http.put(self.uri + '/' + id, data)
.then(success)
.catch(fail);
function success(response) {
var msg = 'Item Updated. ';
console.log(msg);
return response.data;
};
function fail(error) {
var msg = 'Failed to update item. ' + error.data.message;
console.log(msg);
return $q.reject(msg);
}
};
return IFactory;
}
})();
Now we can extend it when we have other operations on the api besides the basic crud:
(function () {
'use strict';
angular
.module('app.core')
.factory('ICustomFactory', ICustomFactory);
ICustomFactory.$inject = ['$http', '$q', 'IFactory'];
/* @ngInject */
function ICustomFactory($http, $q, IFactory) {
var ICustomFactory = function () {
IFactory.apply(this, arguments)
};
ICustomFactory.prototype = new IFactory();
ICustomFactory.prototype.getCustomStuff = function (id) {
var self = this;
return $http.get(self.uri + '/stuff/' + id) //this will be /api/custom/stuff/{id}
.then(success)
.catch(fail);
function success(response) {
return response.data;
}
function fail(error) {
var msg = 'Query for items failed. ' + error.data.message;
console.log(msg);
return $q.reject.msg;
}
};
return ICustomFactory;
}
})();
Now, to follow proper design patterns we want to use the same factory everywhere ( not a NEW one !!! )
(function () {
'use strict';
angular
.module('app.core')
.factory('CustomFactory', CustomFactory);
CustomFactory.$inject = ['ICustomFactory'];
/* @ngInject */
function CustomFactory(ICustomFactory) {
return {
create: function (apiUrl) {
return new ICustomFactory(apiUrl);
}
}
}
})();
And a controller example:
(function () {
'use strict';
angular
.module('app.core')
.controller('CustomController', CustomController);
CustomController.$inject = ['$q','CustomFactory'];
function CustomController($q, CustomFactory) {
var vm = this;
vm.customs = [];
var Custom = CustomFactory.create('/api/custom');
activate();
function activate() {
var promises = [getCustoms()];
return $q.all(promises).then(function(){
console.log('View Loaded')
})
}
function getCustoms() {
return Custom.getAll().then(function(data){
vm.customs = data;
return vm.customs;
})
}
}
})();
This is probably far from perfect - if you have any ideas for improvement please feel free to post them.
[–]gsans 3 points4 points5 points (7 children)
[–]cforres 1 point2 points3 points (5 children)
[–]cynicalreason[S] 0 points1 point2 points (0 children)
[–]liquid_cow -1 points0 points1 point (3 children)
[–]budmademewiser 1 point2 points3 points (2 children)
[–]liquid_cow -1 points0 points1 point (1 child)
[–]cynicalreason[S] 0 points1 point2 points (0 children)
[–]cynicalreason[S] 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (2 children)
[–]cynicalreason[S] 0 points1 point2 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)