Convert Angular HTTP.get function to a service
angularjs, service
Solution
Think in terms of modules and dependency injection.
So, lets say you have these three files
<script src="controllers.js"></script>
<script src="services.js"></script>
<script src="app.js"></script>
You would need three modules
1. Main App Module
angular.module('MyApp', ['controllers', 'services'])
.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/bookslist', {
templateUrl: 'partials/bookslist.html',
controller: "BooksListCtrl"
})
.otherwise({redirectTo: '/bookslist'});
}]);
Notice that the other two modules are injected into the main module, so their components are available to the whole app.
2. Controllers Module
Currently your controller is a global function, you might want to add it into a controllers module
angular.module('controllers',[])
.controller('BooksListCtrl', ['$scope', 'Books', function($scope, Books){
Books.get(function(data){
$scope.books = data;
});
$scope.orderProp = 'author';
}]);
`Books` is passed to the controller function and is made available by the services module which was injected in the main app module.
3. Services Module
This is where you define your `Books` service.
angular.module('services', [])
.factory('Books', ['$http', function($http){
return{
get: function(callback){
$http.get('books.json').success(function(data) {
// prepare data here
callback(data);
});
}
};
}]);
There are multiple ways of registering services.
- service: is passed a constructor function (we can call it a class) and returns an instance of the class.
- provider: the most flexible and configurable since it gives you access to functions the injector calls when instantiating the service
- factory: is passed a function the injector invokes when instantiating the service.
My preference in using the `factory` function and just have it return an object. In the example above we just return an object with a `get` function that is passed a success callback. You could change it to pass an error function too.
Edit Answering @yair's request in the comments, here's how you would inject a service into a directive.
4. Directives Module
I follow the usual pattern, first add the js file
<script src="directives.js"></script>
Then define a new module and register stuff, in this case a directive
angular.module('directives',[])
.directive('dir', ['Books', function(Books){
return{
restrict: 'E',
template: "dir directive, service: {{name}}",
link:function(scope, element, attrs){
scope.name = Books.name;
}
};
}]);
Inject the directive module to the main module in `app.js`.
angular.module('MyApp', ['controllers', 'services', 'directives'])
You might want to follow a different strategy and inject a module into the directives module
Notice that the syntax inline dependency annotation is the same for almost everything. The directive is injected the same Books service.
Updated Plunker: http://plnkr.co/edit/mveUM6YJNKIQTbIpJHco?p=preview
Problem
I'm trying to convert an Angular `HTTP.get` function in my `controllers.js` to a service in `services.js`. The examples I have found all have conflicting ways to implement the service and their choice of names is confusing. Furthermore, the actual angular documentation for services uses yet a different syntax than all the examples. I know this is super simple, but please help me out here. I have `app.js`, `controllers.js`, `services.js`, `filters.js`. app.js ``` angular.module('MyApp', []). config(['$routeProvider', function($routeProvider) { $routeProvider. when('/bookslist', {templateUrl: 'partials/bookslist.html', controller: BooksListCtrl}). otherwise({redirectTo: '/bookslist'}); } ]); ``` controllers.js ``` function BooksListCtrl($scope,$http) { $http.get('books.php?action=query').success(function(data) { $scope.books = data; }); $scope.orderProp = 'author'; } ```