Sunday, August 17, 2014

Making my SPA application in AngularJS

Ok, now that I have some pages and a basic understanding, the possibility of a SPA (Single Page Application) seems the next challenge. A SPA consist of an entry page with somewhere in the middle a ng-view tag, just like this :

<div ng-view>
</div>


In between the two divs you will replace the content with the help of a routing mechanism. To use routing you need to include the angular-route.min.js script in your html page. To load pages into you ng-view use a way with buttons or links that will navigate to another page: My Example:


<div class="container">
<div class="row">
<table>
<tr>
<td><a id="Menubutton" href="#/Contracts"> Contracts </a></td>
<td><a id="Menubutton" href="#/Companies"> Companies </a></td>
<td><a id="Menubutton" href="#/About"> About </a></td>
</tr>
</table>
<div ng-view></div>


You will need routing set up in you app module: Here is an example (my app.js):


var ContractsApplication = angular.module('ContractsApp', ['ngRoute','ngResource','Contracts','Companies']);

ContractsApplication.config(['$routeProvider',
                  function($routeProvider,$routeParams) {
 $routeProvider.
 when('/AddNewOrder', {
  templateUrl: 'add-order.html'

 }).
 when('/Home', {
  templateUrl: 'index.html'

 }).
 
 when('/About', {
  templateUrl: 'About.html'
 }).
 when('/NewContract', {
  controller: 'ContractsFrm',
  templateUrl: 'NewContract.html'
 }).
 
 when('/NewCompany', {
  controller: 'CompaniesFormCtrl',
  templateUrl: 'NewCompany.html'
 }).
 when('/EditCompany/:Companyid', {
  controller: 'CompaniesFormCtrl',  
  templateUrl: 'EditCompany.html'
 }).

 when('/Companies', {
  controller: 'CompaniesCtrl',  
  templateUrl: 'Companies.html'
 }).
 
 when('/Contracts', {
  controller: 'ContractsCtrl',  
  templateUrl: 'Contracts.html'

 });
}]);



As you can see the:

#/Companies
matches
/Companies

in the when part of the router. You will have to pass the template that gets loaded.
The template is not a full HTML page but a html partial. You can also pass a controller to be used in the page partial that gets loaded. You do not have a controller in the page itself.

For instance my About.html looks as following:


<h2>About</h2>
Contract application Version 1.01 Date : 14-aug-2014
 
 A small snip-it indeed ! 
Do not forget to add the scripts you need in the index.html.
Here is my complete index.html:

 
<!DOCTYPE html>
<html lang="en">
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<head>
<title>Contracts</title>
</head>

<body ng-app="ContractsApp">

 <div class="container">
  <div class="row">
   <table>
    <tr>
     <td><a id="Menubutton" href="#/Contracts"> Contracts </a></td>
     <td><a id="Menubutton" href="#/Companies"> Companies </a></td>
        <td><a id="Menubutton" href="#/About"> About </a></td>
    </tr>
   </table>
   <div ng-view></div>

  </div>
 </div>
 <script src="Scripts/angular.min.js"></script>
 <script src="Scripts/angular-route.min.js"></script>
 <script src="Scripts/angular-resource.min.js"></script>
 <script src="Scripts/app.js"></script>
 <script src="Scripts/ContractCRUD.js"></script>
 <script src="Scripts/Contract_Utils.js"></script> 
 <script src="Scripts/Form.js"></script>
 <script src="Scripts/CompanyCRUD.js"></script>
 <script src="Scripts/CompanySrv.js"></script>
 <script src="//code.jquery.com/jquery-1.10.2.js"></script>
 <script src="//code.jquery.com/ui/1.11.0/jquery-ui.js"></script>

</body>
</html>

Modularizing my AngularJS application

Slowly I'm refactoring My Angular application.
I really like to put general functionality in separate files and services. Not an easy task in Angular, since you really have to get the concept right with modules and dependency injection.

My main application in app.js is dependent on Contracts and Companies.
The Contracts module depends on services that I want to use in all my forms, called frmServices.
In Frmservices I want to use the HTTP Service, for instance to have a more generic delete call that I want to use from wherever I like.

With trail and error the structure now looks like this:

Main app.js (partial)

var ContractsApplication = angular.module('ContractsApp', ['ngRoute','ngResource','Contracts','Companies']);

Company.js (partial)
 
var CompaniesApp = angular.module('Companies', ['frmServices']);
 


Form.js (dependent on $http)


var FormApp = angular.module('frmServices', [])                                                                                                                                                                       
.factory("frm", ['$http', function($http) {                                                                                                                                                  
    return {                                                                                                                                                                                                             
        Delete: function(p_Deltext,p_Url,p_Id) {
            var retVal = confirm(p_Deltext);
            if (retVal==true) {
                var httprequest=GloServername + p_Url + "/Delete/" + p_Id;
                $http.delete(httprequest).success(function() {
                    return true;   
                }).error(function(data,status){alert("failure Delete: HTTP code:" + status)});
            }
            return false;
        },

        Update: function() {
            //Do something else here
        }
    }}]);



When you want to use the delete function in the service, do not forget to inject the service in your controller. In this case in the Company.js (the frm injection):
CompaniesApp.controller("CompaniesCtrl",function($http,$scope,$location,frm){

You can then call the delete from within the controller as following:
    if (frm.Delete("Delete ?","RestCompanies",pCompany_id)==true)

Hope this helps. It took me several hours to figure it all out. The nice thing is however you can have a whole hierarchy of dependent modules. Be carfull with your service names however. They have to be unique. There is a lot more refactoring to do, since ultimately I would like to pass a company service to the delete function, that will take care of the delete.

Saturday, August 16, 2014

Refreshing server data in $http request in AngularJS

I'm getting along with my sample Angular project. One of the hurdles I had to take was refreshing my data after going from a list to a data form to change company data. Returning to the list would show the old data. Http requests get cached by the browser when the request string is the same as in a previous request.

Finally I found that generating unique keys with each http request was a simple solution to guarantee that  the http request was actually going to the rest server instead of returning the cached data.

I did it as following (javascript code):


var d = new Date();
var n = d.getTime(); // generate unique key
var httprequest="";
httprequest = "http://localhost:9080/ContractsRestServer/rest/RestCompanies/" + Orderby + "/" + n;
$http.get(httprequest)
        .success(function(data) {
            $scope.Companies=data
        }).error(function(data,status){alert("failure CompaniesController: HTTP code:" + status)});

Off course I also had to change my Java server side code to include the unique key. The signature of the class now looks as following:

package com.testres;

import java.util.List;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
// import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import ContractsDB.Models.*;

// http://localhost:9080/ContractsRestServer/rest/RestCompanies
// http://localhost:9080/ContractsRestServer/rest/RestCompanies/name    to order by name

@Path("RestCompanies")
public class GetCompanies {

 // This method is called if TEXT_PLAIN is request
 
 @GET 
 @Produces("application/json") // MediaType.APPLICATION_JSON)
 @Path("/{orderby}/{key}") 
 public String Get(@PathParam("orderby") String p_OrderBy,@PathParam("key") String p_Key) {
  System.out.println("in getcompanies + " + p_OrderBy  );
        Company_Factory cf = new Company_Factory();
        List<Company> Company_List = cf.QueryCompany("", p_OrderBy);       
        Gson gson = new GsonBuilder().create();
  return gson.toJson(Company_List); 
 }






When you want to cache your data, simply leave out the key.


Wednesday, August 13, 2014

My Eclips AngularJS dev environment

I'm working on my Contracts application with AngularsJS. I'm using Eclips Luna for this development. Maybe not ideal, but since I have to create 3 tiers being Db layer, Rest service layer and UI layer (HTML) I feel it is the best and it is completely free (so is the rest of everything I use to develop the SPA (Single page application).

Here is a screen shot of the 3 projects:










It speaks rather for itself. The Contracts DB project creates a JAR file that is used by the Contracts Rest server application. This way I can separate the work. The ContractsDB contains units test to test all of my Db capabilities, so I can rest assured it will keep working after DB or code changes in my DB layer.

For The rest server and the Contracts web I made two seperate Tomcat Server instances (version 8.01), Like So:


I did this so I can test on one PC the fact that in production the HTML web server will probably be on an other server then the Services implementation. Do not forget the change the port of one of the servers, otherwise the second will not start. You can change the properties f the server by double clicking on it.


Sunday, August 10, 2014

My Java rest service for my Angular Web application

To get all the companies to my web application I had to write a REST service in Java. I'm using the Eclipse Luna version together with the javax.ws libraries from the jersey implementation (see
http://jersey.java.net/ ) 
This is the simplest implementation.

Before that i have written my own data classes and put them into a separate project called ContractsDB. From the Project I export the JAR file and will use it in my Rest project.

I'm not using JPA (Java persistence api), since I think in combination with the web services it is to complicated to get going and to distribute.

My rest service looks as following:


 package com.testres;

import java.util.List;

import javax.ws.rs.GET;
// import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import ContractsDB.Models.*;

// http://localhost:9080/TestRest/rest/RestCompanies
// http://localhost:9080/TestRest/rest/RestCompanies/name    to order by name

@Path("RestCompanies/{orderby}")
public class GetCompanies {

     // This method is called if TEXT_PLAIN is request

    @GET
    @Produces("application/json") // MediaType.APPLICATION_JSON)

    public String Get(@PathParam("orderby") String p_OrderBy) {
        Company_Factory cf = new Company_Factory();
        List&lt;Company&gt; Company_List = cf.QueryCompany("", p_OrderBy);
        Gson gson = new GsonBuilder().create();
        return gson.toJson(Company_List);
    }
}


As you can see I return from  my own query object, also I am using the Google JSon library to return json syntax.

I test the service with a firefox plugin:


It seems to be working, next step will be to create a page and retrieve the data with AngularJS.




Saturday, August 9, 2014

Starting my Angular Project

Last several weeks I have been starting my AngularJS adventures. With the download of the latest version and Eclipse to develop Restfull Services I thought I would build a simple contracts administration. I have put my database in MySql just for convenience. I must say the easiest way to start is just to copy the Angular scripts to a subfolder Scripts in my HTML root directory, and then add the scripts reference to my index.html page.


I use the angular-route.min.js since I want to make a Singe web page application using the ng-view directive. Something that will add to the complexity immediately.

The script tags I put just beforethe end body tag, since i want to load the HTML first. Just to see if the Angular framework works I have put the following code:


<html ng-app>
  <head>
   </head>
  <body>
    <div>
    <input type="text" ng-model="data.message" />
    <h1>{{ data.message }}</h1>
    </div>
    <script src="Scripts/angular.min.js"></script>    
  </body>
</html>



Notice the ng-app and the ng-model="data.message". Both directives will be used to indicate to the Angular java-script that the source should be treated by the angular framework.
If your browser shows : data.message in the screen something is not right. It should present you with an input box and retype everything you type into the box like so: 



if it shows this:



.....somethings wrong. Either you did not add the ng-app tag, or it did not reference the javascripts files in the right way.

If it show the right screen that's it. you're off to a start in the wonderful Angular.Js world.

Sunday, December 13, 2009

Inversion of Control

With the latest Genwise Software factory project we are using a pattern that is called Inversion of Control, or also known as Dependency Injection (what's in a name). Getting our heads around this pattern took a while and it was hard to find a simple sample that just demonstrates the simplest implementation of this technique. (more complex implementations using service locators can be found elsewhere). In this simplest sample a movie database printer prints movies from different movie sources. One is supposed to be memory and the other a text file.

You can download the sample here