//*************** Before ES6 *********************//varcustomer={name:"Jane Doe",handleMessage:function(message,handler){handler(message);},greet:function(){varthat=this;this.handleMessage("Hello, ",function(message){console.log(message+that.name);});}};customer.greet();// "Hello, Jane Doe"// Another option is to use .bind()varcustomer={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 =>) ***************//varcustomer={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 *********************//varsalutation="Hello";vargreeting=salutation+", World";console.log(greeting);// "Hello, World"//*************** In ES6(using ${}) ***************//varsalutation="Hello";vargreeting=`${salutation},World`;console.log(greeting);// "Hello, World"
You can also do computation inside ${} such as the example below:
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
varweatherNote='The weather\n\t'+'today is\n\t'+'sunny';console.log(weatherNote);//*************** In ES6(using ``) ***************//varweatherNote=`Theweathertodayissunny`;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 *********************//varx=100;if(x){varx=2;}console.log(x);// 2//*************** In ES6(using let) ***************//varx=100;if(x){letx=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 *********************//varAPI_BASE_URL="www.asdf.com";API_BASE_URL="qwer";// still able to re-assign API_BASE_URL to another valueconsole.log(API_BASE_URL);// "qwer"//************** In ES6(using const) *************//constAPI_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.
//*************** Before ES6 ****************************************//varmultiplication=function(x,y){returnx*y;}console.log(multiplication());// NaNconsole.log(multiplication(1,2));// 2//*************** In ES6(default function parameters) ***************//varmultiplication=function(x=0,y=0){returnx*y;};console.log(multiplication());// 0console.log(multiplication(1,2));// 2
7. Repeat
1
2
3
4
//*************** In ES6(.repeat()) ***************//varcat="meow".repeat(5);console.log(cat);// "meowmeowmeow"
Below are some references that you can take a look to learn more about ES6.
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.
Note: This addon requires Ember CLI version more than 0.2.0.
Let’s modify the app.js to app.coffee
We are almost done. Now, let’s modify router.js to router.coffee.
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!
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.
Note: sudo npm install protractor -g if you are having permission issue.
Step3: Run Selenium installation script from node_modules/ directory.
Step4: Start standalone Selenium server with the following command:
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.
// 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:
In a new Terminal window, run your configuration file.
Command #2:
You are all set. Hope you enjoy testing your AngularJS application!
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:
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.jsangular.module("services",[]).factory("greet",function(){return{message:"Hello world from factory!"}})
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:
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.
//main.jsangular.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:
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.jsangular.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.
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.jsangular.module("services",[])//.value("message", "Hello world from value!").constant("message","Hello world from constant!").provider("greet",function(){vartype;return{setType:function(value){type=value},$get:function(){return{message:type,}}}})
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!