AngularJS has two services that wrap the native browser XMLHttpRequest
class: $http
and $resource
. The $http
service is comparatively low level and exposes a request and response abstraction around HTTP calls. The $resource
service is more high level and provides an object-level abstraction—that is, loading and saving an object from the server as opposed to making requests directly. Both interact with the server via HTTP.
So, you can send AJAX requests in several different ways
$http
service;$http
service;$http examples
$http
is an AngularJS service for reading data from remote servers.
$http.get(url)
is the function to use for reading server data.
<div ng-app="TestApp" ng-controller="TestCtrl"> <ul> <li ng-repeat="man in men"> {{ man.name + ', ' + man.age + ', ' + man.height }} </li> </ul> </div> <script> var app = angular.module('TestApp', []); app.controller('TestCtrl', function($scope, $http) { var config = { params: {age: 22, height: 180} }; $http.get("/remote/url/", config).success(function(data, status, headers, config) { $scope.men = data; }).error(function(data, status, headers, config) { // log error }); }); </script>
The $http.get()
function returns a "promise" object. This promise object has a success()
and an error()
function. By calling these functions and pass a function to them as parameter you can control what happens when the AJAX call finishes.
The $http
service has several functions you can use to send AJAX requests. These are:
Notice that the $http.post()
and $http.put()
functions take a data parameter which contains data to be sent to the server. The rest of the $http
functions cannot take a data parameter.
Post (create) object to server
var params = {name: 'John', age: 28, height: 180}; $http.post("/remote/url/", params).success(function(data, status, headers, config) { $scope.men.push(data.man); $scope.message = data.msg; }).error(function(data, status, headers, config) { alert( "failure message: " + JSON.stringify({data: data})); });
Put (update) object to the server
$scope.updateMan = function(){ $http.put('/romote/url/' + $scope.man.id, {"men": $scope.man}).success(function(data, status, headers, config){ $scope.man = data.man; }).error(function(response, status, headers, config){ $scope.message = data.message; }); };
Delete object in the server
$scope.delMan = function(man) { $http.delete('/remote/url/' + man.id).success(function(data, status, headers, config){ var index = $scope.men.indexOf(man); $scope.man.splice(index, 1); }).error(function(response, status, headers, config){ $scope.message = data.msg; }); }
$resource examples
The $resource
service is a high-level abstraction around $http
that allows you to operate at the abstraction of objects loaded from the server rather than at the level of individual HTTP requests and responses.
Often our backend data is modelled in a way that naturally fits into the client-side data models in our app. For example, if our app has a list of Man that we show in a stream, a Man model becomes a core data element on both the server and the client.
Additionally, backend services that work on individual models like this often implement a RESTful API where we can easily create, read, update, and delete individual items, or grab lists of items.
The $resource service is not part of the AngularJS core. To use it, you must include the angular-resource.js file and add a dependency on the ngResource module.
The $resource
function has the following signature. Note that square brackets mean the parameter is optional and may be omitted
$resource(url, [paramDefaults], [actions], options);
This function returns a resource object that has a set of functions called actions. Each action corresponds to a different class of HTTP requests.
For the sake of this example, let’s assume we have an API for Man. This API has a few endpoints supporting some common HTTP verbs:
With ngResource
, we can easily wrap this API and interact with it:
var app = angular.module('TestApp', ['ngResource']); app.factory('Man', function($resource) { return $resource('/api/man/:id'); }); app.controller('TestCtrl', function($scope, Man) { // Get all men $scope.men = Man.query(); // Our form data for creating a new Man with ng-model $scope.postData = {}; $scope.newMan = function() { var man = new Man($scope.postData); man.$save(); } // Get specific Man Man.get({id: 1}, function(data) { $scope.man = data; }); });
And then we can easily have a form for creating new Man
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-resource.min.js"></script> <body ng-app="TestApp" ng-controller="TestCtrl"> <form ng-submit="newMan()"> <label>New man:</label> <input ng-model="postData.name" placeholder="Name"> <input ng-model="postData.age" placeholder="Age"> <input ng-model="postData.height" placeholder="Height"> <button type="submit" class="button button-positive">Create</button> </form> </body>
When the user submits this form, the newMan()
function is called, creating a new instance of our Man resource, and then calling $save()
which does an HTTP POST to /api/man
.
We can create a new Man using save
Man.save(data)
We can update the existing Man using $save
var man = Man.get({id: 1}, function() { man.name = "Mark"; man.$save(); });
And we can delete a specific Man by id
Man.delete({id: id});
What if your response of Men is not an array but a more complex json? This typically results in the following error TypeError: Object #Resource has no method 'push'
. Angular seems to expect your service to return a JSON array.
In this case you have to change the $resource
definition accordingly.
app.factory("Man", function($resource) { return $resource("/api/man/:id", {}, { query: { method: "GET", isArray: false } }); }); app.controller("TestCtrl", function($scope, Man) { Man.query(function(data) { $scope.men = data.men; }); });
Tweak $resource
Transform data after request
app.factory('Man', function($resource) { return $resource('/api/man/:id', null, { query: { method: 'GET', isArray: true, transformResponse: function(data, headersGetter) { var items = angular.fromJson(data); console.log(items); return items; } } }); });
Do some work after request
var men = Man.query({}, function(res){console.log(res)}) // or var men = Man.query().$promise.then(function(res){console.log(res)});
Useful links