The $http
service is how AngularJS makes rest API calls. It's capable of
making the common 'GET', 'POST', 'PUT', and 'DELETE' API calls as well as the
less common 'PATCH' and 'HEAD' calls. It can also make jsonp calls for
cross-origin requests.
The setup:
<html>
<head>
<title>$http fun</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.5/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="app" ng-controller="TestCtrl as test">
</body>
</html>
function testService($http) {
this.get = function() {}
}
function TestCtrl(testService) {
var self = this;
self.getMessage = function() {}
}
angular.module('app', [])
.service('testService', testService)
.controller('TestCtrl', TestCtrl)
GET-ing Data
Let's use the get()
method to retrieve some data from a server:
function testService($http) {
this.get = function() {
return $http.get('http://test-routes.herokuapp.com/test/hello')
}
}
function TestCtrl(testService) {
var self = this;
self.getMessage = function() {
testService.get()
.then(function(res) {
self.message = res.data.message;
})
}
}
$http
methods return Angular $q
promises, which allows for clean code flow
via promise chaining. We can use this concept to mutate the returned data.
Let's use this concept to send only the contents of message
back to the
controller:
this.get = function() {
return $http.get('http://test-routes.herokuapp.com/test/hello')
.then(function(res) {
// return the enveloped data
return res.data.message;
})
}
We can now call this from the controller like so:
self.getMessage = function() {
testService.get()
.then(function(message) {
self.message = message;
})
}
Notice how only the messages are being returned.
POST-ing Data
POST-ing data is similar to GET-ing it except we can pass a JavaScript object to be sent along with the request. In our service, we'll create a method that'll allow us to POST a message to an API endpoint and receive an upper-cased version in return:
this.upperCase = function(data) {
return $http.post('http://test-routes.herokuapp.com/test/uppercase', data)
}
Then from the controller:
self.postData = function(message) {
testService.upperCase({message: message})
.success(function(body) {
self.sendMessage = body.message;
})
}
Finally, in our HTML file:
<input ng-model="test.sendMessage" placeholder="Enter a message">
<button ng-click="test.postData(test.sendMessage)">uppercase</button>
In this example, we pass a string from an <input>
field, through the
controller and to the service where $http.post()
sends it off to
the API. When the call returns, the resulting value is passed back
to the controller which updates the views.
Examining the Response Object
The response object passed back via the promise contains several properties that describe the request:
config
: the initial config object used to make the requestdata
: the data returned from the server. If the response type is set to 'application/json', Angular will automatically parse the received data and make it available as an object via thedata
attribute associated on the response object.headers
: this property contains further functions for retrieving header information associated with the requeststatus
: the HTTP status code of the requeststatusText
: accompanying text of the response (e.g. "OK", "Bad Request", etc.)
Error Handling
Because $http
methods return promises, error handling is quite simple. If
the request returns with statusCode
not in the 2xx range, the promise will
be rejected.
success() and error() Methods
The promises returned by $http
have two additional non-standard methods
attached to them: success()
and error()
. These methods behave just like the
then()
and catch()
methods on standard promises accept rather than passing
a standard response object to the callback function, they instead pass the
response properties as function parameters starting with data
. They are
provided merely as convenience functions.