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

1
<div ng-include="'tableTemplate.html'"></div>

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

1
<div my-directive></div>

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');
           });
      }

Leave a Reply