Monday, April 25, 2016

JavaScript Notes

Coming from the Java background, my main problem with JavaScript is encapsulation: global space is not good. I love OO because object is the best place to encapsulate the data. Here are the patterns I would like to follow always.

In the JavaScript, function can be used as :

  • function
  • method
  • constructors
  • classes
  • Module

As a first example, will start with the Module.

Module Pattern

In this pattern, you can define number of privilege method which have access to the secret information such as private variables and methods . For example, setFirstName method can set the name local variable as well as the function getUserFullName has access to the private method getFullName as shown int he following code:

var person = (function (firstName, lastName, age){
  //properties
  var a = age;
  var fname = firstName;
  var lname = lastName;

  //common functions
  function getFullName(f,l){
    return fname+" "+lname;
  }

  return { //open to outside
    getFirstName: function() {return fname},
    getLastName: function(){return lname},
    getAge: function(){return age;},
    getUserFullName: function(){ return getFullName();},
    setFirstName: function(f){fname = f;},
    setLastName: function(l){ lname = l;}
  };
} ("Kite", "Tommy", 45));

The above code is a singleton to create an object.

Classical Inheritance

Sometimes it is frustrated to use prototype in the code. As a Java Developer I would like to have following shortcut:

function Person(firstName, lastName){
  this.fname = firstName;
  this.lname = lastName;
  this.getFirstName = function(){return this.fname;}
  this.getLastName = function() {return this.lname;}
};

Function.prototype.method = function(name, func){
  this.prototype[name] = func;
  return this;
};

Person.method('getFullName', function(greetings){
  return greetings+" "+this.fname+" "+this.lname;
});

You can extend the Function using prototype only once as shown in the prototype.method, then use the method function to create new method as shown in the getFullName().

var p1 = new Person('Ojitha', 'Hewa');
undefined

p1.getFullName("Hello ")
"Hello  Ojitha Hewa"

p1.getFirstName()
"Ojitha"

p1.getLastName()
"Hewa"

Above results shows how to create object and the way to access the methods.

To create a subclass Employee inherited from the Person, need to use the prototype as follows:

//extend from the Person
Employee.prototype = new Person();

Employee.method('setFirstName', function(firstName){
  this.fname = firstName;
});

Employee.method('setLastName', function(lastName){
  this.lname = lastName;
});

But you can add the new functions without prototype. Following code shows how to access these functions;

var e1 = new Employee(1234)
undefined
e1.setLastName('Hewa')
undefined
e1.setFirstName('Oj')
undefined
e1.getFullName('Hello')
"Hello Oj Hewa"
e1.getFirstName()
"Oj"
e1.getLastName();
"Hewa"

Prototypal Inheritance

This is class free way of inheritance of object from object. For example create a person object using object literal and create an employee object using Object.create method.

ar person = {
  fname: 'oj',
  lname: 'Kuma',
  getFullName: function(greetings){
    return greetings+" "+this.fname+" "+this.lname;
  }
};

var employee = Object.create(person);
employee.employeeId = 1234;
employee.getEmployeeId = function(){
  return this.employeeId;
}

As shown in the following text, you can access the methods belongs to employee as well as person via employee object.

employee.getEmployeeId()
1234
employee.getFullName()
"undefined oj Kuma"
employee.getFullName('Hello')
"Hello oj Kuma"

functional Inheritance

Let us get back to the classical inheritance. The modular pattern can be used with classical inheritance to achieve the functional inheritance:

function Person (firstName, lastName, age){

  //common functions
  function getFullName(f,l){
    return firstName+" "+lastName;
  }

  return { //open to outside
    getFirstName: function() {return firstName},
    getLastName: function(){return lastName},
    getAge: function(){return age;},
    getUserFullName: function(){ return getFullName();},
    setFirstName: function(f){firstName = f;},
    setLastName: function(l){ lastName = l;}
  };
};

function Employee(firstName, lastName, age, employeeId){
  var that = Person(firstName,lastName,age);
  that.employeeId = employeeId;
  that.getEmployeeId = function(){return that.employeeId;}
  that.setEmployeeId = function(employeeId){that.employeeId = employeeId;}
  return that;
}

The difference of the two classes is only employeeId available to the Employee class everything else inherited from the Person class. The Employee augment the Person and return that object. Here how to access:

var e1 = Employee('Oj', 'Hewa', 35, 1234);
undefined
e1.getEmployeeId()
1234
e1.setEmployeeId(4321)
undefined
e1.getEmployeeId()
4321
e1.getFirstName()
"Oj"
e1.getUserFullName()
"Oj Hewa"
e1.employeeId
1234
e1.firstName
undefined

Another thing to notice is that firstName and lastName are completely hidden. Something can be do the the employeeId as well.

Here the function to navigate through the dom;

      function walkTheDom(node, func){
        func(node);
        node = node.firstChild;
        while (node) {
          walkTheDom(node, func);
          node = node.nextSibling;
        }
      }

this can be call as walkTheDom(document, function(node){console.log(node);}) in the debugger.

Sunday, April 10, 2016

Java Web development with AngularJS

Angular Basics

AngularJS is MVC based fronted framework. To make the things easier, I’ve use Atom editor with the the atom-html-preview plugin (Ctrl+Shift+H). Anytime you can invoke developer tools pressing by Alt+Command+i.

Using MVC

Here the most basic Angular+Bootstrap mvc example. In this example, there are three users listed in the ex1 and controller is FriendController which is used as friendList in the HTML.

<html>

<head>
  <script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
  <script src="https://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
  <link rel="stylesheet" href="bootstrap-3.3.6-dist/css/bootstrap.css"/>
  <script type="text/javascript" src="angular-1.5.3/angular.js"></script>
  <script type="text/javascript" src="bootstrap-3.3.6-dist/js/bootstrap.js"></script>

  <script type="text/javascript">
    angular.module('ex1',[])
      .controller('FriendController', function(){
      var friendList = this;
      friendList.friends=[
        {name:'Ojitha', age:10},
        {name:'Jhon', age:20},
        {name:'Terry',age:30}
      ];
  });
  </script>

  <style type="text/css">
    .even {
      color: red;
    }
    .odd {
      color: blue;
    }</style>
</head>

<body ng-app="ex1">
  <div ng-controller="FriendController as friendList">
    <p><input type="text" ng-model="searchFor" size="30"/></p>
    <ul>
        <div class="panel panel-primary" ng-repeat="friend in friendList.friends | filter: searchFor"
        ng-class="{even:$even, odd:$odd}">
          <div class="panel-heading">{{friend.name}}</div>
          <ul>
              <li ng-repeat= "(k, v) in friend">
                <strong>{{k}}</strong> = {{v}}
              </li>
          </ul>
        </div>
    </ul>
  </div>
</body>
</html>

Forms

You can add a new friend to the friends as follows using HTML form tag.

    <form ng-submit="friendList.addFriend()">
      <input type="text" ng-model="friendList.name", size="30" placeholder="enter name here..."/>
      </br>
      <input type="int" ng-model="friendList.age" size="3"/>
      <br/>
      <input type="submit" value="add" class="btn-primary"/>
    </form>

There are two elements added to the controller: name and age. When submit the form, these elements should be added to the friends array in the javascript section:

friendList.addFriend = function(){
    friendList.friends.push({name:friendList.name, age:friendList.age});
      }

Ajax

In the above html, friendList.friends hardcoded domain model. Using Ajax, REST interface can be called to fetch friends details as follows:

    angular.module('ex1',[])
      .controller('FriendController', function($http){
      var friendList = this;
      $http.get('http://localhost:8080/mf/friends').success(function(data){
        friendList.friends = data;
      });
  });

The url specified in the get method send the GET request to the REST service and accept the JSON result.

REST service

I’ve used Spring REST to generate the REST service.

package au.com.blogspot.ojitha.managefriends.controller;

import au.com.blogspot.ojitha.managefriends.domain.Friend;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by ojitha on 10/04/2016.
 */
@RestController
public class FriendsController {

    @RequestMapping(value = "/friends",method = RequestMethod.GET)
    public List<Friend> allFriends(){
        List<Friend> friends = new ArrayList<>();
        Friend f1 = new Friend();
        f1.setName("Ojitha");
        f1.setAge(40);
        friends.add(f1);

        Friend f2 = new Friend();
        f2.setName("Mark");
        f2.setAge(30);
        friends.add(f2);

        Friend f3 = new Friend();
        f3.setName("Tom");
        f3.setAge(24);
        friends.add(f3);

        return friends;
    }
}

Here the domain class

package au.com.blogspot.ojitha.managefriends.domain;

/**
 * Created by ojitha on 10/04/2016.
 */
public class Friend {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

It is important to note that, I’ve created spring boot application for the simplicity.

AngularJS Service layer

Of course this is not the backend service layer. However, presentation service layer support reusability and the extendability. For example, in the following complete source, Friends service has been created and injected to the controller. In addition to that, there service is singleton.

<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
    <script src="https://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>

    <link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
    <script data-require="angular.js@1.5.3" data-semver="1.5.3" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>

    <script type="text/javascript">
        angular.module('ex1',[])
                .controller('FriendController', ['Friends', function(Friends){
                    var friendList = this;
                    Friends.load().success(function(data){
                        friendList.friends = data;
                    }).error(function(data, status, headers, config){
                        if (status === 404) {
                            window.alert('not found');
                        } else {
                            window.alert('Unknown error');
                        }
                    });
                }]);
    </script>

    <script type="text/javascript">
        angular.module('ex1')
                .factory('Friends', function($http){
                    var friendRequest = null;
                    return {
                        load: function(){
                            if (!friendRequest){
                                friendRequest = $http.get('/mf/friends');
                            }
                            return friendRequest;
                        }
                    };
                });
    </script>


    <style type="text/css">
        .even {
            color: red;
        }
        .odd {
            color: blue;
        }</style>
</head>

<body ng-app="ex1">
<div ng-controller="FriendController as friendList">
    <p><input type="text" ng-model="searchFor" size="30"/></p>
    <ul>
        <div class="panel panel-primary" ng-repeat="friend in friendList.friends | filter: searchFor"
             ng-class="{even:$even, odd:$odd}">
            <div class="panel-heading">{{friend.name}}</div>
            <ul>
                <li ng-repeat= "(k, v) in friend">
                    <strong>{{k}}</strong> = {{v}}
                </li>
            </ul>
        </div>
    </ul>
</div>
</body>
</html>

As shown in the above code, the two javascript script can be separately put in to the two JavaScript source files and evolve separately.

Packaging JS Libraries

In the above html code, angular, bootstrap and query libraries are loading from the well known CDNs. The advantage is if the other applications use the same CDN, then the these libraries are only once downloaded. However, if you need to provide your own files then follow the following procedure.

  1. The first thing to install is Homebrew, the reason is it is very easy to install as well as install the applications via that.

    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

    First install the ruby and then install the Homebrew.

  2. Install node to use the npm package installer

    brew install node

    Used the Homebrew to install the node.

  3. Now use the node to install bower:

    npm install bower

    I installed above bower package to use locally only, If you need system wide, then npm install -g bower is the command to use.

  4. Now use the bower to install all the required javascript libraries.

    bower install angular
    bower install angular-animate
    bower install angular-ui-bootstrap-bower
    bower install bootstrap
  5. After install what you want, check the installed versions and the dependencies.

    bower list

    if you want to remove any package, you can use bower uninstall <package> .

  6. Now change the HTML file to include the JS libraries:

    <script src="bower_components/angular/angular.js"></script>
    <script src="bower_components/angular-animate/angular-animate.js"></script>
    <script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
  7. Test the HTML after replace.

Friday, March 18, 2016

Scala Notes

Maps

Here the example of Map and the immutable map.

import java.net.URL
import java.util.Scanner


val in = new Scanner(
  new URL("https://raw.githubusercontent.com/rdwallis/alice/master/src/main/webapp/WEB-INF/book/10.txt").openStream())
var count = Map[String, Int]()
//var count = scala.collection.mutable.Map[String, Int]()

while (in.hasNext()){
  val word = in.next()
  count.+=(word->(count.getOrElse(word,0)+1))
  //count(word) = count.getOrElse(word,0)+1
}

count("Alice")

Above code segment, mutable Map is commented. This is an exercise I did from the Scala for the Impatient.