AngularJS Services and $http
A service is an object that does a specific job, such as talking to a server, and can be shared by many controllers.
Built-in Services
AngularJS includes many services. Their names start with $.
| Service | Job |
|---|---|
$http | Sends requests to a server and gets data back |
$timeout | Runs code after a delay (like setTimeout) |
$interval | Runs code again and again (like setInterval) |
$location | Reads and changes the page URL |
$log | Writes messages to the browser console |
$q | Creates and combines promises |
To use a service, add it as a parameter of your controller. AngularJS injects it for you.
$http: Loading Data
Example
<div ng-app="usersApp" ng-controller="UsersController">
<p ng-if="loading">Loading...</p>
<p ng-if="error">{{ error }}</p>
<ul>
<li ng-repeat="u in users">{{ u.name }} ({{ u.email }})</li>
</ul>
</div>
<script>
angular.module("usersApp", []).controller("UsersController", function ($scope, $http) {
$scope.loading = true;
$http.get("https://jsonplaceholder.typicode.com/users")
.then(function (response) {
$scope.users = response.data;
})
.catch(function () {
$scope.error = "Could not load users. Please try again.";
})
.finally(function () {
$scope.loading = false;
});
});
</script>Leanne Graham (Sincere@april.biz) Ervin Howell (Shanna@melissa.tv) ...
$http.get returns a promise. The data arrives in response.data. The response also has status (such as 200) and headers.
In very old code you may see .success() and .error() instead of .then(). Those methods were removed in AngularJS 1.6. If you upgrade an old app, change them to .then() and .catch().
Sending Data with $http.post
Example
$scope.save = function () {
$http.post("/api/admissions", { name: $scope.name, course: "web" })
.then(function (response) {
$scope.message = "Saved with id " + response.data.id;
});
};$timeout and $interval
Use these instead of setTimeout and setInterval. AngularJS then knows the data changed and updates the page.
Example
app.controller("ClockController", function ($scope, $interval, $timeout) {
$scope.welcome = "";
$timeout(function () {
$scope.welcome = "Welcome to the student portal!";
}, 2000);
$scope.time = new Date().toLocaleTimeString();
var timer = $interval(function () {
$scope.time = new Date().toLocaleTimeString();
}, 1000);
$scope.$on("$destroy", function () {
$interval.cancel(timer);
});
});If you use plain setTimeout, the page may not update, because AngularJS does not notice the change. This is a common bug in older apps.
Creating Your Own Service
Put shared logic in a service so controllers stay small. The most common way is module.factory:
Example
var app = angular.module("shopApp", []);
app.factory("CartService", function () {
var items = [];
return {
add: function (name, price) {
items.push({ name: name, price: price });
},
list: function () {
return items;
},
total: function () {
return items.reduce(function (sum, i) { return sum + i.price; }, 0);
}
};
});
app.controller("CartController", function ($scope, CartService) {
$scope.cart = CartService;
CartService.add("School Bag", 1800);
CartService.add("Water Bottle", 450);
});Example
<div ng-controller="CartController">
<p>{{ cart.list().length }} items, total Rs {{ cart.total() }}</p>
</div>2 items, total Rs 2250
A service is created once, so every controller that injects CartService shares the same cart.
factory, service and provider
| Method | How it is written |
|---|---|
factory | A function that returns an object |
service | A constructor function; data is put on this |
provider | Configurable version, set up in app.config |
All three create services. In old code you will see factory most often.
Exercise
Exercise
Why should you use $timeout instead of setTimeout in AngularJS?
