Introduction
Angular JS has become a really popular framework as it allows extending the HTML to create templates and enable two-way binding between view and model.
The real world applications in addition to templating depend on the backend servers for executing the core business logic.
Angular provides a rich built in support for communication with the server, it not only provides the low level mechanism which acts as building block to communicate with
the servers, but it also provides built-in wrappers for communication with RESTful services.
In this tip, we will focus on how to communicate with server using Angular JS.
Background
AJAX is the heart of single page applications. It enables the communication with the backend servers without page refresh. This single feature has revolutionized
the way web applications are developed. A typical web application now focuses on fetching the data and layout (HTML) separately.
This is different from the way ASP/JSP applications were developed where the data and layout were merged at the server to generate HTML, which was streamed to the browser.
As AngularJS applications are also single page applications, it provides rich built in support for AJAX communication.
Let’s dive into the details of the support that Angular provides for server side communication.
Communicating with $http
In Angular, the basic building block for communication with server is $http
service. The $http
service is a core Angular service that facilitates communication with
the remote HTTP servers via the browser's XMLHttpRequest
object or via JSONP.
This service provides basic functionalities like:
GET
POST
HEAD
DELETE
PUT
JSONP
Angular API uses the Promise
interface based approach for server side communication. This ensures that all the server related calls are non-blocking/asynchronous calls,
which means that the response from the server is returned at some time in future. The Promise
interface ensures that the response will be handled accordingly as and when
it will arrive. There are two method names, success
and error
for handling the response from the server.
$http.get("empMgr", {params: {op: 'get'}})
.success(function(data, status, headers, config) {
$scope.employee = data;
})
.error(function(data, status, headers, config) {
alert("failure");
});
};
In the above example, an AJAX GET
request is fired to find the details of an employee
with id as 100
. This call doesn’t wait for the response from the server.
When the response from the server is received sometime in future, appropriate function success
or error
is called depending on the response from the server.
$http.post
In case we need to submit a data to the server using POST
method, we can use $http.post
API. Following is an example of posting the data to the server.
var dataToPost = {firstName: "Allen", lastName: "John"};
var queryParams = {params: {op: 'saveEmployee'}};
$http.post("empMgr" , dataToPost, queryParams)
.success(function(serverResponse, status, headers, config) {
$scope.postresponse = serverResponse.data.firstName + " " + serverResponse.data.lastName;
}).error(function(serverResponse, status, headers, config) {
alert("failure");
}
);
The above example POSTs the employee data to the server. This call too is asynchronous. When the server is done with handling the save request, the response
returns and the relevant method success
/error
is invoked.
Handling POST in Angular
Please note that $http.post
of Angular is different from jQuery.post
.
Angular posts the data as JSON in the http body with content-type
set as application/json
, where as jQuery posts the values with content-type as 'application/x-www-form-urlencoded;charset=utf-8
'
so we need to put some codebase at the server to parse the http body to fetch to request body or we need to configure the Angular codebase to send the request as key value pair.
Configuring the $http Service Request
Although default implementation of $http.get,$http.post
etc. is good enough to serve most of the purpose, there may be some specific use cases where we need
to customize the default APIs. For example, we may have to set some custom headers, transform request and response, set custom timeout, enable/disable cache
and set the response type.
$http
service provides an inbuilt mechanism to customize the http requests using the “config
” object. All the APIs of $http.X
take the last parameter as config
object to customize the requests.
For example, we can set the authorization token in HTTP header for get request using the header
property of config
object.
$http.get("empMgr",
{
params: {op: 'get'},
headers: {"AUTH_TOKEN": "1234567890"}
})
.success(function(data, status, headers, config) {
$scope.employee = data;
})
.error(function(data, status, headers, config) {
alert("failure");
});
};
});
$http
service can be invoked by passing only the config
object too. The config
object supports the following properties:
The supported options are :
$http({
method: string, // GET, POST, PUT, HEAD etc
url: string, // URL of resource being requested
params: object, // Query parameters, if not string goes as JSON string
data: string or object, // Data to be sent as request message data
headers: object, // Map representing the HTTP header
transformRequest: function transform(data, headersGetter) or an array of functions, // Transforms request
transformResponse: function transform(data, headersGetter) or an array of functions, // Transforms response
cache: boolean or Cache object, // Boolean to turn cache on or off
timeout: number, // Timeout to wait for response from server
withCredentials: boolean
});
Communicating with RESTful Services
As already discussed, $http
is a low level API for server side communication used to communicate with the
server. In real world applications, we have to deal with data objects which represent an entity in the software
ecosystem. In a normal scenario, we have to write codebase for common functionality like create, read, update, delete of
these objects using $http
service.
myAppModule.factory('EmployeeService', ['$http', function($http) {
var url = 'rest/employee';
return {
get: function(empID) {
return $http.get(url + '/' + empId);
},
save: function(employeeObj) {
var url = employeeObj.id ? url + '/' + employeeObj.id : url;
return $http.post(url, employeeObj);
},
query: function(empID) {
return $http.get(url + '/' + empID.id + '/reportees');
},
calculateSalary: function(employee) {
return $http.post(url + '/' + employee.id, employee, {params: {admin: true}});
}};
}
]);
In order to address this repetition of tasks, Angular provides built in support to create a service using $resource
object.
This object provides common functionalities like:
Get
Save
Query
Remove
Delete
out of the box, without even writing a single line. It also provides the functionality to create new methods in the service.
The following code snippet explains the concept:
angularModule.factory("EmployeeListService", ['$resource', function($resource){
return $resource('rest/employee/:empId',
{empId: '@id'},
{calculateSalary: {method: 'POST', params: {charge: true}, isArray: false}});
}]) ;
Now the EmployeeListService
<code>
Service has the following methods out of the box without writing a single line of code:
EmployeeListService.get()
EmployeeListService.save
EmployeeListService.save
EmployeeListService.query()
EmployeeListService.remove()
EmployeeListService.delete()
Custom Methods
In addition to the above methods, $resource
service provides us the functionality to create new methods. This helps us to make custom RESTful calls the server.
The following sample shows how to define a custom method in $resource
service:
angularModule.factory("EmployeeReporteeService", ['$resource', function($resource){
return $resource('rest/employee/:empId/reportees',
{empId: '@id'},
{contactNumbers: {method: 'GET', params: {admin: true}, isArray: true}});
}]);
How to Use Include $resource Object?
Let’s have a look at how to include this $resource
service in codebase:
<script src=" angular-resource.js"></script>
angular.module(‘samplemodule’, [‘ngResource’]);
myAppModule.factory('EmployeeService', ['$resource', function($resource) {
The $resource
service accepts 1 required parameter and 2 optional parameters:
- URL; required: The URL where the resource is available
- Query params: Parameters to be passed with URL
additional functions: Additional methods we want to add to the service.
Source Code
The attached codebase is a Maven based project, created in Netbeans IDE.
On the server side, it uses Java Servlet for $http.get
and $http.post
. For RESTful services creation, it uses Jersey 1.8.
It also uses the GSON library for converting the List/Employee
object to JSON.
Summary
In this article, we have discussed only the basics of AngularJS communication with server. In the next article, we will focus on details of $q, Cross-Site Request Forgery, Security, testing codebase.
Reference
- http://angularjs.org/