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:
GETPOSTHEADDELETEPUT 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.saveEmployeeListService.saveEmployeeListService.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/