1. Arrow function/Fat Arrow function - shorthand using => syntax.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//*************** Before ES6 *********************//
var fullName = function(firstName, lastName){
  return firstName + lastName;
};

//*************** In ES6(using =>) ***************//
var fullName2 = (firstName, lastName) => {
  return firstName + lastName;
};

var fullName3 = (firstName, lastName) => firstName + lastName;

console.log(fullName("Bart ", "Simpson"));    //"Bart Simpson"
console.log(fullName2("Marge ", "Simpson"));  //"Marge Simpson"
console.log(fullName3("Maggie ", "Simpson")); //"Maggie Simpson"

The arrow syntax also omit the need for var that = this assignment or .bind(this).

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
//*************** Before ES6 *********************//
var  customer = {
  name: "Jane Doe",

  handleMessage: function (message, handler) {
    handler(message);
  },

  greet: function () {
    var that = this;
    this.handleMessage("Hello, ", function(message){
      console.log(message + that.name);
    });
  }
};

customer.greet(); // "Hello, Jane Doe"

// Another option is to use .bind()
var  customer = {
  name: "Jane Doe",

  handleMessage: function (message, handler) {
    handler(message);
  },

  greet: function () {
    this.handleMessage("Hello, ", function(message){
      console.log(message + this.name); 
    }.bind(this));
  }
};

customer.greet(); // "Hello, Jane Doe"

Now, there is a simple way using the arrow function.

1
2
3
4
5
6
7
8
9
10
11
12
//*************** In ES6(using =>) ***************//
var  customer = {
  name: "Jane Doe",

  handleMessage: (message, handler) => handler(message),

  greet: function () {
    this.handleMessage("Hello, ", (message) => console.log(message + this.name));
  }
};

customer.greet(); // "Hello, Jane Doe"

2. Template Strings

1
2
3
4
5
6
7
8
9
10
11
//*************** Before ES6 *********************//
var salutation = "Hello";
var greeting = salutation + ", World";

console.log(greeting); // "Hello, World"

//*************** In ES6(using ${}) ***************//
var salutation = "Hello";
var greeting = `${salutation}, World`;

console.log(greeting); // "Hello, World"

You can also do computation inside ${} such as the example below:

1
2
3
var  x = 1;
var  y = 2;
console.log(`${x} + ${y} = ${x+y}`); // 1 + 2 = 3

Another cool thing is multi-line string. Using backticks you can easily create a multi-line string.

1
2
3
4
5
6
7
8
9
10
11
12
var weatherNote = 'The weather\n\t'
    + 'today is\n\t'
    + 'sunny';

console.log(weatherNote);

//*************** In ES6(using ``) ***************//
var weatherNote = `The weather
    today is
    sunny`;

console.log(weatherNote);

3. let - allows block scoping to be created.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//*************** Before ES6 *********************//
var x = 100;
if (x) {
  var x = 2;
}

console.log(x); // 2
//*************** In ES6(using let) ***************//
var x = 100;
if (x) {
  let x = 2;
}

console.log(x); // 100

4. const - assign constant variables that should not be re-assign

1
2
3
4
5
6
7
8
9
//*************** Before ES6 *********************//
var API_BASE_URL = "www.asdf.com";
API_BASE_URL = "qwer"; // still able to re-assign API_BASE_URL to another value
console.log(API_BASE_URL); // "qwer"

//************** In ES6(using const) *************//
const API_BASE_URL = "www.asdf.com";
API_BASE_URL = "qwer";
console.log(API_BASE_URL); // Will trigger an error saying attempting to override 'API_BASE_URL' which is a constant.

5. Spread Operator - the 3 dots ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//*************** Before ES6 *********************//
var fruits = ["strawberry", "orange", "apple"];
var moreFruits = ["pear", "grape"];
var allFruits = ["pineapple", fruits, "watermelon", moreFruits];

console.log(allFruits);
//allFruits returns ["pineapple", ["strawberry", "orange", "apple"], "watermelon", ["pear", "grape"]]

//*************** In ES6(using ...) ***************//
var fruits = ["strawberry", "orange", "apple"];
var moreFruits = ["pear", "grape"];
var allFruits = ["pineapple", ...fruits, "watermelon", ...moreFruits];

console.log(allFruits);
//allFruits returns ["pineapple", "strawberry", "orange", "apple", "watermelon", "pear", "grape"]

6. Default function parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//*************** Before ES6 ****************************************//
var multiplication = function(x, y){
  return x*y;
}

console.log(multiplication()); // NaN
console.log(multiplication(1, 2)); // 2

//*************** In ES6(default function parameters) ***************//
var multiplication = function(x=0, y=0){
  return x*y;
};

console.log(multiplication()); // 0
console.log(multiplication(1, 2)); // 2

7. Repeat

1
2
3
4
//*************** In ES6(.repeat()) ***************//
var cat = "meow".repeat(5);

console.log(cat); // "meowmeowmeow"

Below are some references that you can take a look to learn more about ES6.

References:

  1. Egghead
  2. lukehoban/es6features
  3. Top 10 ES6 Features Every Busy JavaScript Developer Must Know
  4. MDN

Setting Up Ember CLI with CoffeeScript

Ember CLI is a powerful command line utility for Ember.js. By default, Ember CLI generates JavaScript files for your ember application. However, you can enable CoffeeScript easily.

Create a new Ember CLI application:

$ ember new my-new-app

Next, install ember-cli-coffeescript addon.

$ ember install ember-cli-coffeescript

Note: This addon requires Ember CLI version more than 0.2.0.

Let’s modify the app.js to app.coffee

`import Ember from 'ember'`
`import Resolver from 'ember/resolver'`
`import loadInitializers from 'ember/load-initializers'`
`import config from './config/environment'`

Ember.MODEL_FACTORY_INJECTIONS = true

App = Ember.Application.extend
  modulePrefix: config.modulePrefix
  podModulePrefix: config.podModulePrefix
  Resolver: Resolver

loadInitializers(App, config.modulePrefix)

`export default App`

We are almost done. Now, let’s modify router.js to router.coffee.

`import Ember from 'ember'`
`import config from './config/environment'`

Router = Ember.Router.extend
  location: config.locationType

Router.map ->

`export default Router;`

Lastly, run ember server. You should see “Welcome to Ember.js”. The next time you use ember generate command, all files will be generated in CoffeeScript.

Now, you can start working on your ambitious web application using CoffeeScript!

Why test?

Website complexity has been growing enormously and manual testing is becoming more and more difficult to catch errors that might be introduced from our code. However, testing should not be neglected as writing effective test would in turn help us to make sure that our code is working correctly as intended.

It also gives us the opportunity to catch and fix errors before deploying to production. Writing test also helps the developer to understand each piece of the code better and would have an overall big picture of how each piece of code works together.

The good news is that AngularJS is written with testing in mind. Check-in of Angular source is tested before it is being accepted into the core. This blog post will talk about E2E(End-to-End) testing. E2E testing is testing from the end user’s perspective of how our code should work. In AngularJS, E2E testing is done using Protractor.

Protractor

Protractor is built on top of Selenium’s WebDriverJS. The Protractor Project is public in Github. Anyone can follow the project issues and help out the community.

Protractor is integrated with Jasmine, thus E2E and unit testing can both be written using Jasmine. In Protractor, tests are run against your application that is running in a real browser and test scripts interact with the running browser like a user would.

Install Protractor

Step1: Install NodeJS

Step2: Install Protractor globally

$ npm install protractor -g 

Note: sudo npm install protractor -g if you are having permission issue.

Step3: Run Selenium installation script from node_modules/ directory.

$ ./node_modules/protractor/bin/webdriver-manager update 

Step4: Start standalone Selenium server with the following command:

$ ./node_modules/protractor/bin/webdriver-manager start

Note: Java JDK is required in order to start Selenium server.

Once installation is completed, the protractor command is now available. You can type in protractor --help to checkout the options available.

#Configuration Protractor needs a configuration file to tell it which tests to run, how to connect a webdriver server and set options for reporting. You can take a look at referenceConf.js to see a complete list of configurations that are available to be used.

If the referenceConfig.js is too much for you to digest, there are example configuration files located at ./node_modules/protractor/example which are more concise and you may add things along when needed. Below is an example of the chromeOnlyConf.js example taken from the example folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// An example configuration file.
exports.config = {
  // Do not start a Selenium Standalone sever - only run this using chrome.
  chromeOnly: true,
  chromeDriver: '../selenium/chromedriver',

  // Capabilities to be passed to the webdriver instance.
  capabilities: {
    'browserName': 'chrome'
  },

  // Spec patterns are relative to the current working directly when
  // protractor is called.
  specs: ['example_spec.js'],

  // Options to be passed to Jasmine-node.
  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000
  }
};

In line 14, specs: ['example_spec.js'] is an example of test written in Jasmine. This file is also available in the example folder. You can specify more than one file to test under the specs option. For example:

1
2
3
4
specs: [
    'example_spec.js',
    'main_spec.js'
],

Protractor will execute the tests sequentially, meaning that example_spec.js will run first followed by main_spec.js

Now that you have your configuration file and test written. You just need to run 2 commands to start testing your application.

Command #1:

$ ./node_modules/protractor/bin/webdriver-manager start

In a new Terminal window, run your configuration file.

Command #2:

$ protractor chromeOnlyConf.js

You are all set. Hope you enjoy testing your AngularJS application!

References

Services

In my previous blog post, I talked about the differences between value and constant services. This blog post will continue to discuss the factory, service and provider services in AngularJS.

factory

factory is an AngularJS service that allows you to inject a function. The syntax for declaring factory service is as below:

1
2
3
4
angular.module("services", [])
    .factory("factoryName", [function(){
       //function logic
    }])

factory comes in handy when you would like to inject a function instead of a variable that the value service provide. Below is a simple example of using factory to inject a function that returns the greet message, “Hello world from factory!”.

1
2
3
4
5
6
7
//service.js
angular.module("services", [])
    .factory("greet", function() {
        return {
            message: "Hello world from factory!"
        }
    })
1
2
3
4
5
//main.js
angular.module("root", ["services"])
    .controller("index", function($scope, greet) {
        $scope.message = greet.message;
    });

If you would like to try this code on your browser, you can use the index.html from my previous blogpost.

service

service is pretty much like factory whereby you can inject function using service. The difference is that in service, constructor function is injected and variables and methods are created with this keyword. An example of how a service is created is as below:

1
2
3
4
5
6
7
8
angular.module("services", [])
    .service("serviceName", [function(){
    //function logic
    this.pi = 3.14;
    this.method1 = function(){
       //method1 logic
    } 
}])

I have also created a simple service to print “Hello world from service!” in the example below:

1
2
3
4
5
6
7
8
//service.js
angular.module("services", [])
    .service("greet", function() {
        this.message = function()
        {
            return "Hello world from service!";
        }
    })
1
2
3
4
5
//main.js
angular.module("root", ["services"])
    .controller("index", function($scope, greet) {
        $scope.message = greet.message();
    });

provider

Another useful AngularJS services is provider. It uses the $get method which is available in AngularJS. provider is a function that must return an object containing the $get property. Let’s take a look at an example on how to use provider to print our “Hello world from Provider!” message.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//service.js
angular.module("services", [])
    .provider("greet", function() {
        var type;
        return {
            setType: function (value) {
              type = value
            },
            $get: function(){
              return {
                message: type + "!",
              }
            }
        }
    })
1
2
3
4
5
6
7
8
9
//main.js
angular.module("root", ["services"])
    //the function argument needs to be the providerName + "Provider"
    .config(function (greetProvider) {
      greetProvider.setType("Hello world from Provider")
    })
    .controller("index", function($scope, greet) {
        $scope.message = greet.message;
    });

Things to note on this example is the greetProvider. We need to make sure that it matches the provider name that you have created and concatenate it with the Provider word in order for AngularJS to recognize it. Also, note that provider is able to be injected to config().

Below is a summary table of all the services I have discussed.

                   
services     use $get?     present during configuration phase?     present during run phase?
constant     No     Yes     Yes
value     No     No     Yes
factory     No     No     Yes
service     No     No     Yes
provider     Yes     Yes     No
                   

Further recommended readings to learn more about services in AngularJS are listed below:

Services

In AngularJS, there are five different service types.

  • value
  • constant
  • factory
  • service
  • provider

Each type of services has its own unique characteristics that makes it useful for handling a certain type of problems. This blog post will talk about value and constant services.

value

value is the simplest of all services. A value service literally provides predefined value to the object. Below is the service.js. Here we defined a value called message that contains the string "Hello world from value!"

1
2
3
//service.js
angular.module("services", [])
	.value("message", "Hello world from value!");

main.js below defines the controller for this app. Notice that services module is injected to this module. This is required because the components defined in the services module are by default not accessible by the root module. Line 2 means that the root module depends on the services module to work.

1
2
3
4
5
//main.js
angular.module("root", ["services"])
	.controller("index", ["$scope", "message", function($scope, message) {
		$scope.message = message;
	}]);

Lastly, is the index.html that will print the message defined by the value in service.js. This index.html will be used throughout this blog post.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- index.html -->
<!DOCTYPE html>
<html ng-app="root">
<head lang="en">
    <meta charset="utf-8">
    <title>Services-Constant-Value</title>
</head>
<body>
    <div ng-controller="index">
        <h1>{{message}}</h1>
    </div>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular.min.js"></script>
    <script type="text/javascript" src="main.js"></script>
    <script type="text/javascript" src="service.js"></script>
</body>
</html>

constant

Declaring constant is very similar to how you would declare a value. Below is an example of how constant is declared; referencing from the above example:

1
.constant("message", "Hello World from constant!")

If you were to replace line 3 in the service.js with the above code, you will get Hello World from constant! printed out on your browser. You may be wondering what is the difference between value and constant then since both of them seems to perform similar task?

The difference between them is that constant service is able to be injected to the config() but value cannot. This is because config() are executed before services are instantiated and therefore, we cannot inject the value service because it is yet to be created.

Now, we’ll take a look at a more concrete example on how constant service is injected to the config(). The example below will output Hello world from constant! to your browser.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//service.js
angular.module("services", [])
    //.value("message", "Hello world from value!")
    .constant("message", "Hello world from constant!")

    .provider("greet", function() {
        var type;
          return {
            setType: function (value) {
                type = value
            },
            $get: function(){
                return {
                  message: type,
                }
            }
          }
    })
1
2
3
4
5
6
7
8
//main.js
angular.module("root", ["services"])
    .config(function (greetProvider, message) {
        greetProvider.setType(message)
    })
    .controller("index", function($scope, greet) {
        $scope.message = greet.message;
    });

Let’s do some experiment and try to uncomment line 3 and comment line 4. Test out the code on your browser and see what happens.

You will not see the Hello world from constant! output anymore. If you take a look at your console you will see an error message. This is because value service does not exits yet when the config() executes.

I’ll discuss about the remaining three services ( factory, service and provider) in my next post. Stay tuned!