AngularJS Fundamental Concepts for Building Web Applications: Part 4
This article continues the four-part series on AngularJS fundamentals and provides an advanced example of using web forms to post data to a back-end service. (If you are unfamiliar with AngularJS, please read my previous three AngularJS fundamentals articles before continuing.)
Almost every web-based application has to deal with using web forms to collect, submit, and update important application input data coming from the user. One simple example is a registration form. Countless web applications have these forms to acquire useful user information that the site can use latersuch as a user login and password to gain access to important yet private resources that are user specific.
A database is essential for persisting user input so that it can be available again across repeated application sessions. Most (if not all) OO languages such as C# and Java have components for directly accessing and managing databases. However, JavaScript-based languages such as Angular do not have components for dealing directly with a database because (similar to other JavaScript-based languages) Angular is not a server-side language. It is actually a client-side language that interacts with users only at their machine level.
To communicate with a back-end server such as a database server, Angular needs to use a server-side OO language that provides this functionality through the use of OO database components. This communication is often done through RESTful web services that are often written in a server-side OO language such as Java or C#.
The example in this article uses a RESTful web service back-end to handle the client-side requests coming from Angular. (The details of this RESTful service are not explained because you need to know only that the service can handle database-related operations.)
Posting Data with Web Forms
Web forms is a generic term that refers to forms in a web-based application used to collect user input. Let's look at an example that includes everything needed to validate and post form data:
<html lang="en"> <head> <meta charset="UTF-8"> <title>Example - example-example98-production</title> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.19/angular.min.js"></script> <style type="text/css"> .css-form input.ng-invalid.ng-dirty { background-color: #FA787E; } .css-form input.ng-valid.ng-dirty { background-color: #78FA89; } </style> </head> <body ng-app="formExample"> <div ng-controller="ExampleController"> <form novalidate name="formx" class="css-form"> <table> <tr><td align='right'>Name</td><td align='left'><input type='text' name='name' ng-model='user.name' required value=''></td></tr> <tr><td align='right'>Email</td><td align='left'><input type='email' name='email' ng-model='user.email' value=''></td></tr> <tr><td align='right'>Password</td><td align='left'><input type='text' name='password' ng-model='user.password' value=''></td></tr> <tr><td align='right'>Verify Password</td><td align='left'><input type='text' name='passwordx' ng-model='user.passwordx' value=''></td></tr> </table> <button ng-click="reset()">RESET</button> <button ng-click="update(user)">SAVE</button> </form> </div> <script> angular.module('formExample', []) .controller('ExampleController', ['$scope', function($scope) { $scope.master = {}; $scope.update = function(user) { if ($scope.formx.$valid) { $scope.master = angular.copy(user); alert('Form has been validated successfully'); } }; $scope.reset = function() { $scope.user = angular.copy($scope.master); }; $scope.reset(); }]); </script> </body> </html>
Next, you'll see how to post this form's data to a web service after the form's data is validated. For an example on doing form validation (using the same form for convenience), see my third article in this series: "AngularJS Fundamental Concepts for Building Web Applications: Part 3."
Notice the 'if ($scope.formx.$valid) {' block in the code. This condition tells the controller to do something with the data (such as post it to a back-end server) only if all the validation has passed for the form's property fields. In this code block, you will post the data to the service.
Angular uses a condensed form of code to represent the typical AJAX JavaScript submit template code. (The code for submitting data via AJAX using pure JavaScript is shown in the code that follows.)
The traditional way of making a request to the server from AJAX applications (using XMLHttpRequests) involves getting a handle on the XMLHttpRequest object, making the request, reading the response, checking the error codes, and processing the server response.
It goes something like this:
var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readystate == 4 && xmlhttp.status == 200) { var response = xmlhttp.responseText; } else if (xmlhttp.status == 400) { // Handle error } }; // Setup connection xmlhttp.open("GET", "http://myserver/api", true); // Make the request xmlhttp.send();
This code gets lengthy, but Angular comes to the rescue with the $http service. Using the example above, the following code can be used with the $http service to pass the form's post data to a back-end service:
$http.post('api/user', $scope.master ).success(function(data, status, headers, config) { // Do something successful }).error(function(data, status, headers, config) { // Handle error });
The code above posts the $master object, which is just a copy of the user model object as a serialized JSON object to the back-end service.
The final code for handling the code submission for the registration example above becomes the following:
angular.module('formExample', []) .controller('ExampleController', ['$scope', function($scope) { $scope.master = {}; $scope.update = function(user) { if ($scope.formx.$valid) { $scope.master = angular.copy(user); $http.post('api/user', $scope.master ).success(function(data, status, headers, config) { // Do something successful }).error(function(data, status, headers, config) { // Handle error }); } };
By default, the $http service sends the data as JSON. The default content header used by the service is Content-Type: application/json.
To specify a different header or any additional headers, simply use the headers collection:
headers: {'Authorization': 'Basic Qzsda1515432'},
For the complete $http service reference, see the Angular documentation at https://docs.angularjs.org/api/ng/service/$http.