Simple AngularJS REST Example
This is a simple AngularJS example that uses the Bootstrap framework for styling.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> </head> <body> <div ng-app="myApp" ng-controller="formController"> <div class = "container"> <h3>PUT Request</h3> <script type="text/ng-template" id="tableTemplate.html"> <div class="table-responsive"> <table ng-show="formSubmitted" class="table table-striped"> <thead> <tr> <th class="col-md-2">id</th> <th class="col-md-5">name</th> <th class="col-md-5">email</th> </tr> </thead> <tbody> <tr ng-repeat="x in names"> <!-- iterate through [{...},{...}, ...] --> <td>{{ x.id }}</td> <td>{{ x.name }}</td> <td>{{ x.email }}</td> <tr> </tbody> </table> </div> </script> <form class="form-horizontal" ng-submit = "processForm()" role = "form"> <div class="form-group"> <label class="col-sm-2 control-label">id:</label> <div class="col-sm-10"> <input type = "text" name = "id" ng-model = "formData.id"> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">name:</label> <div class="col-sm-10"> <input type = "text" name = "name" ng-model = "formData.name"> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">email:</label> <div class="col-sm-10"> <input type = "email" name = "email" ng-model = "formData.email"> </div> </div> <button class="btn btn-success" ng-disabled="error || incomplete"> <span class="glyphicon glyphicon-save"></span> Save Changes </button> </form> <div ng-include="'tableTemplate.html'"></div> </div> </div> <script> var app = angular.module('myApp',[]); app.controller("formController", function($scope,$http){ $scope.formData = {}; $scope.processForm = function() { // PUT /users/id var url = 'http://localhost/angular/users/' + $scope.formData.id; var data = '{"name": "' + $scope.formData.name + '", "email":"' + $scope.formData.email + '"}'; $http({method: 'PUT', url: url, data: data}).success(function(response) { $scope.names = response; // display the table when the form is submitted $scope.formSubmitted = true; }); /* // GET /users $http({method: 'GET', url: 'http://localhost/angular/users'}).success(function(response) {$scope.names = response;}); // GET /users/id var url = 'http://localhost/users/' + $scope.formData.id; $http({method: 'GET', url: url}).success(function(response) {$scope.names = response;}); // POST /users var data = '{"name": "' + $scope.formData.name + '", "email":"' + $scope.formData.email + '"}'; $http({method: 'POST', url: 'http://localhost/users', data: data}).success(function(response) {$scope.names = response;}); // DELETE /users/id var url = 'http://localhost/users/' + $scope.formData.id; $http({method: 'DELETE', url: url}).success(function(response) {$scope.names = response;}); */ } }); </script> </body> </html> |
Route all requests to index.php
.htaccess:
1 2 3 | RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [QSA,L] |
index.php:
On the server side we use the Slim PHP micro framework for handling the REST requests.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | <?php header('Content-Type: application/json'); require 'Slim/Slim.php'; \Slim\Slim::registerAutoloader(); $app = new \Slim\Slim(); $app->get('/users', 'getnames'); $app->get('/users/:id', 'getname'); $app->post('/users', 'addname'); $app->put('/users/:id', 'updatename'); $app->delete('/users/:id', 'deletename'); $app->run(); function getnames() { $out = array(); $out[0]['id'] = 1; $out[0]['name'] = 'John Doe'; $out[0]['email'] = 'johndoe@angular.com'; $out[1]['id'] = 2; $out[1]['name'] = 'John Hancock'; $out[1]['email'] = 'johnhancock@angular.com'; echo json_encode($out); } function getname($id) { $out = array(); if ($id == 1 || $id == 'tom'){ $out[0]['id'] = $id; $out[0]['name'] = 'John Doe'; $out[0]['email'] = 'johndoe@angular.com'; } if ($id == 2 || $id == 'dick'){ $out[0]['id'] = $id; $out[0]['name'] = 'John Hancock'; $out[0]['email'] = 'johnhancock@angular.com'; } echo json_encode($out); } function addname() { $jsonmessage = \Slim\Slim::getInstance()->request(); $message = json_decode($jsonmessage->getBody()); $out = array(); $out[0]['name'] = $message->name . " has been added"; $out[0]['email'] = $message->email . " has been added"; echo json_encode($out); } function updatename($id) { $jsonmessage = \Slim\Slim::getInstance()->request(); $message = json_decode($jsonmessage->getBody()); $out = array(); $out[0]['id'] = $id; $out[0]['name'] = "updated to: " . $message->name; $out[0]['email'] = "updated to: " . $message->email; echo json_encode($out); } function deletename($id) { $out = array(); $out[0]['id'] = $id; $out[0]['name'] = $message->name . " has been deleted"; $out[0]['email'] = $message->email . " has been deleted"; echo json_encode($out); } ?> |
Slim returns the following JSON response for a GET request.
1 | [{"id":1,"name":"John Doe","email":"johndoe@angular.com"},{"id":2,"name":"John Hancock","email":"johnhancock@angular.com"}] |
AngularJS Custom Directives
An alternative to using the built-in directive
is to place the data binding expression into a custom directive as follows:
1 2 3 4 5 6 7 | app.directive('myDirective', function() { return { replace: true, restrict: 'AE', //E = element, A = attribute, C = class, M = comment templateUrl: 'tableTemplate.html' } }); |
and replace the ng-include directive with
AngularJS automatically makes the connection between the my-directive directive and the directive name myDirective by removing the dash and converting the result to camelCase syntax.
There are many other properties that can be used in directives. Some of the key ones are shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 | template: '<div>{{ myVal }}</div>', // Use this template controller: controllerFunction, //Embed a custom controller link: function ($scope, element, attrs) { // DOM manipulation element.bind('click', function () { element.html('You clicked me!'); }); element.bind('mouseenter', function () { element.css('background-color', 'yellow') }); element.bind('mouseleave', function () { element.css('background-color', 'white'); }); } |