Develop a CRUD application using AngularJS and WildFly

This tutorial shows how to build a full CRUD (create, read, update, delete) application which uses a REST web service deployed on WildFly 8 application server and AngularJS for the User Interface.

This is the second tutorial about AngularJS and REST Web service, let’s recap what we have learnt so far:

Now we will enable as well CREATE and DELETE operations on the ng-grid which needs to be synchronized with the server side. Even if it looks quite complex, you will see it just requires a couple of classes on the server side and one html page that I developed with a few days of experience on AngularJS.
Let’s see the code:
Here is the server side REST service which contains one method for each operation (create, read, update, delete) required to do:

@Stateless
@Path("/service")
public class SimpleRESTService {

    @PersistenceContext
    EntityManager em;

    // Intercepts an HTTP GET to query for the Person Entity. Produces a JSON styled list of Person Entities
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Person> getPersonList()

    {
        
        Query query = em.createQuery("FROM Person");
        List<Person> customerList = query.getResultList();
        return customerList;
    }

    // Intercepts an HTTP POST to update an existing Person. Data is coming in JSON format
    @POST
    @Path("/save")
    @Consumes(MediaType.APPLICATION_JSON)
    public void save(String message) {
    
         JsonReader reader = Json.createReader(new StringReader(message));
         JsonObject obj = reader.readObject();
         String name = obj.getString("name");
         String surname = obj.getString("surname");
         String address = obj.getString("address");
        
         Query query = em.createQuery("FROM Person where name = :name and surname = :surname");
         query.setParameter("name", name);
         query.setParameter("surname", surname);
         Person person = (Person) query.getSingleResult();
         person.setAddress(address);
         em.persist(person);
    }
    // Intercepts an HTTP PUT. Inserts a new Person Entity from data which is coming in JSON format
    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    public void newPerson(String message) {
        
         JsonReader reader = Json.createReader(new StringReader(message));
         JsonObject obj = reader.readObject();
         String name = obj.getString("name");
         String surname = obj.getString("surname");
         String address = obj.getString("address");
         Person person = new Person();
         person.setName(name);
         person.setSurname(surname);
         person.setAddress(address);
       
         em.persist(person);    
    }
    // Intercepts an HTTP POST. Deletes a Person Entity. Data is coming in JSON format
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("/delete")
    public void delete(String message) {
        
         JsonReader reader = Json.createReader(new StringReader(message));
         JsonObject obj = reader.readObject();
         String name = obj.getString("name");
         String surname = obj.getString("surname");
             
         Query query = em.createQuery("delete FROM Person where name = :name and surname = :surname");
         query.setParameter("name", name);
         query.setParameter("surname", surname);
         query.executeUpdate();  
    }
}

And here is the User Interface which uses a set of javascript libraries, including AngularJS, jQuery and ng-grid package for the grid:

<head lang="en">
    <style = "text/css"> .gridStyle { border: 1px solid rgb(212,212,212); width: 600px; height: 400px; } </style>
    <meta charset="utf-8">
        <link rel="stylesheet" type="text/css" href="https://rawgithub.com/angular-ui/ng-grid/2.0.7/ng-grid.css" />
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
        <script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
    </head>
    <script language="javascript"> var app = angular.module('myApp', ['ngGrid']); function MyCtrl($scope, $http) { $http.get('http://localhost:8080/rest-angular/rest/service'). success(function (data) { $scope.users = data; }); $scope.removeRow = function (name, surname) {; // Delete from Grid var index = this.row.rowIndex; $scope.gridOptions.selectItem(index, false); $scope.users.splice(index, 1); // Server side $http.post('http://localhost:8080/rest-angular/rest/service/delete', { name: name, surname: surname }). success(function (data) { alert('delete completed!'); }); }; $scope.saveItem = function (name, surname, address) { $http.post('http://localhost:8080/rest-angular/rest/service/save', { name: name, surname: surname, address: address }). success(function (data) { alert('update completed!'); }); } $scope.addRow = function () { $scope.hidden = true; }; $scope.insertRow = function () { // Update ng-grid $scope.users.push({ name: $scope.myForm.name, surname: $scope.myForm.surname, address: $scope.myForm.address }); $scope.hidden = false; // Persist on database $http.put('http://localhost:8080/rest-angular/rest/service', { name: $scope.myForm.name, surname: $scope.myForm.surname, address: $scope.myForm.address }). success(function (data) { alert('insert completed!'); }); }; $scope.gridOptions = { data: 'users', enableRowSelection: false, enableCellEditOnFocus: true, multiSelect: false, columnDefs: [{ field: 'name', displayName: 'name', enableCellEdit: false }, { field: 'surname', displayName: 'surname', enableCellEdit: false }, { field: 'address', displayName: 'address', enableCellEdit: true }, { field: '', displayName: 'Save', enableCellEdit: false, cellTemplate: '
        <button id="editBtn" type="button" ng-click="saveItem(row.entity.name, row.entity.surname,row.entity.address)" >Save</button>' }, { field: '', displayName: 'Delete', enableCellEdit: false, cellTemplate: '
        <button id="editBtn" type="button" ng-click="removeRow(row.entity.name, row.entity.surname)" >Delete</button>' }] }; } 
    </script>
    <body ng-controller="MyCtrl">
        <div class="gridStyle" ng-grid="gridOptions"></div>
        <button ng-click="addRow()">New Person</button>
    </body>
    <div ng-show="hidden">
        <form>
            <input type="text" name="firstName" ng-model="myForm.name">First name 
                <br />
                <input type="text" name="surname" ng-model="myForm.surname">Last name 
                    <br />
                    <input type="text" name="address" ng-model="myForm.address">Address 
                        <br />
                        <button ng-click="insertRow()">Save</button>
                    </form>
                </div>
            </html>

If you have gone through the first tutorials this code should not seem too complicated. Basically the ng-grid is a component which is backed by an array of data defined in the users scope variable.

  $scope.gridOptions = {
            data: 'users',
            enableRowSelection: false,
            enableCellEditOnFocus: true,
            multiSelect: false,
            . . . . .
   }

The users scoped variable is initially queried using an HTTP get:

 $http.get('http://localhost:8080/rest-angular/rest/service').
        success(function (data) {
            $scope.users = data;
        });

As you can see from the UI, the application includes now a set of buttons:

angularjs tutorial

The Save button which enables saving the Person in case you have modified the editable fields (address is editable):

$scope.saveItem = function (name, surname, address) {
	$http.post('http://localhost:8080/rest-angular/rest/service/save', {
		name: name,
		surname: surname,
		address: address
	}).
	success(function (data) {
		alert('update completed!');
	});
}

The Delete button which deletes the Person from the grid in two steps: at first saving the selected item in “index” and then using index to purge the item from the list:

var index = this.row.rowIndex;

$scope.gridOptions.selectItem(index, false);
$scope.users.splice(index, 1);
alert('delete completed!');

// Server side
$http.post('http://localhost:8080/rest-angular/rest/service/delete', {
                name: name,
                surname: surname
});

Finally the New Person button which triggers the addRow function. reveals an hidden div and pushes the row to the grid and persists the state with an HTTP PUT to the REST service:

  // Update ng-grid
  $scope.users.push({
        name: $scope.myForm.name,
        surname: $scope.myForm.surname,
        address: $scope.myForm.address
   });
       $scope.hidden = false;

       // Persist on database
       $http.put('http://localhost:8080/rest-angular/rest/service', {
         name: $scope.myForm.name,
         surname: $scope.myForm.surname,
         address: $scope.myForm.address
         }).
         success(function (data) {
            alert('insert completed!');
     });

In order to hide/show the new Person div, I’ve used a basic directive of AngularJS named ng-show:

 <div ng-show="hidden">

angularjs jboss wildfly

This directive is a simple way to show/hide part of the DOM structure, using a variable to control the visibility of it.

Here is the full source code of this example. If you have got AngularJS skills and want to improve this code, maybe adding a fancy modal dialog or so, just mail me and I’ll be glad to mention your contribution. Happy AngularJS coding !