Getting Webstorm to work with Angular2, and TypeScript

Wednesday, September 2, 2015

Well, I finally found the time to start looking into Angular 2, so naturally I went to the website to do the quick start demo. I got it working but I did have a some hangups getting my IDEs (yes that plural) to work with Angular 2. This is understandable considering at this writing Angular 2 is in "Alpha".

The quickstart I am doing is located on the Angular 2 site.

Get the Correct Version

First off, by default, Webstorm runs TypeScript 1.4, so you are going to have to get the latest version of the typescript via NPM.

$ npm install -g tsc

The current version as of this writeing is 1.5.3.

Once it is install you will neet to tell Webstorm to use this version.

TypeScript Languages and Preference settings - Sett the bin folder location

Run the Correct Command Parameters

Once you have the correct version, Webstorm will still complain about the attributes. So you will need to tell it the following:

  • What module system you are using. In this case I am using "system".
  • You will need to tell it what version of JavaScript to compile to. I am compiling to "ES5"
  • Next to prarameters take care of the decorators of the class statment.

Webstorm Typescript settings - setting the command parameters.

After that, following the directions on the quickstart example, everything worked fine.

 

Real Time Twitter Stream Component Using Node, Express, Socket.IO, and React on the client.

Friday, August 21, 2015

Introduction

So where I work, we have a large legacy app that we would like to modernize without have to rewrite the entire application from scratch. We have been looking at the React framework because as there site states, "you can try it out on a small feature" and it won't impact the rest of your application. It also helps that it was developed and supported by the team at Facebook.

If you are not familiar with React, it is another client side framework, developed by Facebook, but unlike Angular, Ember, etc, React only focuses on the "View" portion of your MVC application.

What's a Virtual DOM

React uses what they call a "virtual DOM" to interact with DOM elements, so when you as developer are working with React, you actually never get a direct reference to a DOM element, but instead you write JSX code which is very similar to HTML and then React manages the interactions with the DOM for you.

This is where React really shines, because they optimized the interaction to be really fast. So whatever changes you want to make to the DOM, you make the changes in the JSX code, and then React figures the fastest possible way to make the changes to the DOM behind the scenes.

The Stream with Node, Twitter, and Socket.IO

I have discussed building a realttime stream before using Node, so I won't  go into too much details there, but here I will say that this time I am using Socket.IO and since Twitter has real time streaming APIs, I decided to use that for streaming purposes.

 

The above code is pretty straight forward. I am using Express to handle starting up the Node application, and then I have brought in two node packages (Socket.IO and Twitter). So once the application starts, I then kick off Socket.IO to start publishing on a socket and then I kickoff Twitter to start listening for tweets that have the word "JavaScript' in it.

Note: for obvious reasons I did not check in the twitter.js file in the secret folder but basically it is the following. You just need to supply your own Twitter credentials. You can set that up on there application site.

The Client Side

On the client side I am then listening for the stream of tweets via Socket.IO and when a tweet comes in I am firing off a callback function that will update the list of tweets.

The React Code

I have broken my React code into three different files for demo

Twitter-Feed Component

The fist file is parent file and it contains the starting point where React is going to take over the DOM and inject my code.

Since in React, you are building components, the basic way do that is to call the React.createClass function. Inside that function you can set several properties as well as add your own properties to create the component.

Ultimately, once a component is built, I then call the React.render function which takes two parameters (the parent component, and in this case, the DOM element I am attaching the component to.

The properties in my TwitterFeed class are as follows:

  • getInitialState: this property takes a function that allows you set the initial state of properties I am going to use. In my case I have a tweets array. It is recommended that this property only be called in your parent component.
  • addTweet: this is a function I created to add a tweet to the tweet list and then setting the state. The state is what React uses to pass data from one component to the other. It is recommended that only the parent component can change the state. All child conponents are immutable and only listen for changes made by the parent.
  • componentWillMount: this is a React event that fired right before the component is rendered. There are various event similar to this one like componentDidMount which fire immediately after the component is rendered.
  • render: this is the function the renders the final HTML to the DOM. Inside this render function I am calling the child component TwitterList and passing that component the tweets array from the state.

Twitter-List Component

This component takes the tweets from the parent Twitter-Feed component and create the DOM container which is a DIV and then makes a call to its child to create a single tweet component.

This components gets the tweets from the parent via the "props" object.

Also note that am calling a propTypes property. This is useful as it sets the expectation of what type of data it expects. When this is set and you don't pass in the correct data to the component, React will send a nice error explaining what went wrong in the console.

Tweet Component

The final child component builds the single tweet row. It is passed the tweet from the parent Twitter-List component

The Final Result

Obviously I need to work on the presentation a little bit but when the tweet list is automatically being updating realtime as the tweets are being made.

Live Twitter Stream

I have uploaded to code to GitHub, so take a look and let me know what you think. 

TypeScript, Angular and Factories - Another Gotcha (Classic Functions vs Arrow Function)

Wednesday, August 5, 2015

In my last post I talked about how AngularJs Factories need to be instantiated first before they are returned to the calling code.

I came across another problem while converting my JavaScript Angular code to TypeScript and that is how public functions are created in JavaScript depending on how you structure them in TypeScript.

Consider the following TypeScript code:

Which then generates this JavaScript code:

The problem here is the code that is generated builds a function by creating a prototype and the way this code is structured, "this" is referring to the global lexical scope and not scope of this class. So this.$http is undefined.

Funny thing is I did not originally write the code this way but using Visual Studio and Resharper, the code suggestion asked me if I wanted to change it.  Hey! Why not?? Looks cleaner.

Here is the slightly different TypeScript example, this time using arrow function to implement the needed function:

And again, here is the generated JavaScript

Now the generated getUser function is in my constructor as a closure function and the "this" has been preserved by defining it with the "_this" variable. Plus, I think this approach is easier to read.

I think the point here is that in TypeScript, you should try as much as possible to opt for the arrow functions. As matter of fact, if you go the TypeScript Handbook site, they talk about this in detail.

TypeScript, Angular and Factories, Services and Providers

Monday, August 3, 2015

I have been refactoring an Angular project of mine to use TypeScript. I have been doing this for a few reasons:

  • To be able to start using the EcmaScript 6 and beyond coding features.
  • To make it easier to upgrade to Angular 2 in the future.
  • To take advantage of TypeScrips typing and other features.

One of the issues I have come accross while doing this excercise is that all my services are actually Angular Factories.

Angular has three types of services you can have to reuse logic accross your application and they are services, factories, and providers.

Factories:

Factories are typically the most common way to create these components. A factory is basically a function call that returns an object and that object contains properties and functions.

Services:

Services are similar to factories except that they are instaniated when you call them. So the functionality you want to reuse you would put the logic on the "this" keyword which is essentially attaching the functionality to the service itself.

When you use a service Angular will autimatically call it using the "new" keyword.

Providers

Providers are a little more involved, but they are useful when you want to setup some configuration before befure you actually call it. It is the only type of service that is available in the "config" section of a module whcih is executed first, so you can use it at that point to set it up and then call it later in a controller for example.

The problem in TypeScript

Because in TypeScript you create interfaces and then classes that impliment those interfaces, factories will not new up your class. So the following will not work in TypeScript.

The code that is generated looks like this:

To get around this issue, I had to "new up" the classes myself before I returned them as a factory. 

The generated JavaScript code now looks like this:

So since this is the case, you might as well start using services rather than factories if you are going to use TypeScirpt, but if you are going to use factories, remember to instantiate them first before you inject them into your code.

AngularJs 2.0 - RIP Controller, $scope, and angular.module

Monday, October 27, 2014

Well, I just went through the slide deck of a presentation that Igor Minar gave at the ng-europe conference.

There wasn't much details, but in the deck it says that controller, $scope, and the angular.module command are going away. That's like the most commonly used pieces of the framework.

At first, I was a little taken back by this revelation, but the more I think about it, the more it make sense. Lately, I have tended to just have one line of code in a controller that basically attached a service to the $scope, and the latest craze I've seen is the "Controller As syntax".

On the down side, this seems like totally different paradigm for Angular and a totally new approach to take in and get accustom too. Then again, with ECMAScript 6 coming out soon as well, I'll be learning a lot of new syntax already, so might as well throw Angular 2.0 in too. Two birds one stone.

Anyhow, what do you think about these changes?

UPDATE:

Some more details have emerged about Angular 2.0 and were written about here: "AngularJS 2.0 Details Emerge"

UPDATE:

The keynote session on Angular 2.0 Core has been posted on youtube.

 

Unit Testing a Service that Makes an API Call Using $httpbackend

Friday, August 22, 2014

Introduction

This is part of a series on Unit Testing in AngularJS. You can see my others posts:

Creating a Single Page Application will inevitably require making an API call to a service at some point, and AngularJs provides two mechanisms to do accomplish this in its framework. The one instance is using the ngResource module, and the other approach is using the $http service. Personally, I am sort of torn as to what approach to use but I am finding my self gravitating more towards using the $http service just because it is more customizable. I think ngResource shines if you have a predictable set of RESTFUL API calls and you just want to make calls and get responses back, but if you want so more control of things like exception management, or provide a chain of promises, I find the $http service to be more straight forward in setting up.

$httpBackend

Another nice thing the $http service is that is comes with the corresponding $httpBackend service which can be used for mocking calls so your unit test have no external dependencies. After all, that is whole point of a unit test is that it is self contained and not reliant on any outside factors.


The Service

So in this example I have a service that makes an API call to get the friends for a current user:

 

This service has a GET call and a POST call and I want to write a test that will test a mock of the POST call.


The Test Setup

So lets look at the unit test and talk about what is going in this code.

So the first thing that is done is that we need to define our service and also define the $httpBackend service that will be mocking our calls.

I am also defining a mocked response that will be returned one the service is called.

In the beforeEach section, the service and $httpBackend are injected into our environment before each test.

And then after each call we want to ensure that the calls were expected to be made were actually made and that there were no exceptions thrown on those calls.

The Unit Test

Here is the first line of code from the test

$httpBackend.expectPOST('/api/friends/refresh').respond(refreshResponse);

 

This tells the $httpBackend service to expect a POST call to be made to a service and that it will return the refreshResponse object that was defined at the top of the page.

The next lines of code are the actual execution of the service.

var deferredResponse =  friendsApiService.refreshUsers();

var users;

deferredResponse.then(function(response){

    users = response.data;

});

Since we want to preserve the asynchronous nature of the call while at the same time be able to test the response of the call we will then need to flush the response. This will explicitly flush any pending request so that when we can evaluate the response it returns within the unit test. If we did not do this, since our call is asynchronous, our test would finish before the call was actually completed.

Once the flush is complete, we now can evaluate our response to see of our test is working.

 

 

Unit Testing a Simple Controller in AngularJs

Tuesday, August 12, 2014

Introduction

This is part of a series of post related to how to set up and execute unit testing in AngularJs.

In this post, I will show an example of unit testing a simple controller.

In this case I have a started building a controller, and one of the first things I want to test is a collapsible panel inside my view. The way the panel works is when at first the user initially goes to view that has a list of items, at the top of the view there is a button that opens and closes a panel that contains a search text box so the user can filter the items on the page.


The Controller Code

So to start out, my new controller looks like this:

 

The $scope initially sets the isSearchCollapsed property to true, in which the view uses to indicate the panel is closed.

Here is the Jade view that shows or hides the panel.

 

Using the Angular UI directive, the panel slides open and closed based on the value of the isSearchCollapsed property. The value of that property is change every time the toggleSearchCollapsed is executed.


The Test Code

To test the controller code, I need to be able to replicate the controller and its scope in the test environment and Angular gives us a way to do that with two built in functions. Lets look at the code

First thing I need to do is to replicate the controller's scope so I can then attach it to the replicated controller. The $rootScope object has a function called $new which will do that for me. This function basically is used to create child scopes from the base scope.

The next thing I need to do is replicate the controller assigning our newly created scope to that controller. Angular uses the $controller service internally to instantiate controllers, and we can use it to instantiate our controller in our test environment.

Once that is set up we are ready to start testing, and in this case, I have three tests.

  • Starting from scratch my first test is there just to make sure I have successfully replicated the controller and it's scope.
  • The second test, makes sure the isSearchCollapsed property is initially set to false.
  • The third test, validates that when the toggleSearchCollapsed is triggered that the value of the isSearchCollapsed is changed. Since my second test passed and I know the initial value will be true, when I call the function and test the value again it should be false.

Unit Testing a Simple Service in AngularJs

Monday, July 14, 2014

Introduction

When testing in AngularJs, I have found that once you have everything setup correctly, unit testing with Jasmine is not all that complicated. However, when I first started testing in AngularJs, getting things setup right was a bit hit or miss for me. At the time, the documentation for testing wasn't all that definitive so it took me a little longer to grasp the concepts than probably should have been needed.

So in this post, I am going to show how I test a simple service that takes an array of directory paths as a string and parses it out into an array of arrays. Its a simple test for a service that has no dependencies and only one function.

I am basically building on my previous post where I showed how to setup a unit testing environment using NodeJs, GruntJs, KarmaJs, and Jasmine.


The Service

So in this example, I am taking an AngularJs factory that returns one function. This function should take an array of paths and convert them into an array of array of directories.

The whole point of encapsulating this code is that not only is it testable, but is also mockable, and it is reusable.


The Unit Test

So here is the test:

The way I setup a unit test for the module, is I divide the test module into three different sections.

  1. The first section I include any variables that will be used by all the tests. This includes things like the scope, mocks, services, controllers etc. On a side note, if my mock data becomes too big, I separate them out into a different file and place the file in a folder called mocks and then reference them from there. My Karma.conf.js file then will need a reference to this folder.
  2. The next section is the most critical section and that is the section that sets everything up before each test runs.
  3. The last section is the section that handles all the tests.

Let me focus on the second section as that for me has always been the trickiest to get right.

BeforeEach

Jasmine comes with two global variables (beforeEach and afterEach), and as the names describe, the beforeEach runs before each test, while the afterEach runs after each test.

Here I am only using the beforeEach to set up the tests.

Module

The module command is used to specify what AngularJs module you are going to test. You need not worry about any other dependent modules, at this point, the module routine is only specific to the module you currently want to test, even if you have other dependent modules.

Inject

The inject function wraps objects into an injectable function and is where I am initializing the service. In this case I am only referencing my service that I want to test since I don't have any other dependencies.

Notice the underscores in the parameters.These underscores are actually ignored by the injector but allow us differentiate between what is being injected and the module level variable that we want to use for all out tests so they can be assigned accordingly.

The Actual Tests

Finally, the last part of the file contains the actual tests themselves.

If I am using a TDD approach, the first thing I do is make sure the service exists. This is represented by the test, "should be defined as a service". Once this test passes, I am then ready to move on to my next test.

I then test to make sure the method I am actually testing in the service exists. This test is represented by the test, "should have a function called getReportList". Again, once this test passes, I can then move to me next tests.

Then my last two tests, test that the function is actually returning what I am expecting it to return.

Conclusion

Hope that helps. In later posts I will show some different unit tests, such as testing a controller, testing a service that has a $HttpBackend dependency, and testing a controller that has a service dependency. In those posts I hope to cover things like mocks, spies, and the $HttpBackend service as well. 

Angular Unit Testing - Getting setup with Jasmine, Karma, and Grunt

Tuesday, June 24, 2014

As a developer coming from an ASP.Net, C# background, I had come to appreciate the ability to be able to unit test my code. I find that I am not all that great a programmer, and often times the unit tests I write have brought to surface a bug that I would have introduced had I not had a unit test in place to discover the bug in the first place.

In the past, I had not given much thought to do JavaScript unit tests. I had just assumed that it wasn't really possible to do them without a lot of jumping through hoops. However, with AngularJs, unit testing isn't all that difficult. I have found that once I have gotten over the initial hurdle of getting everything setup, unit testing JavaScript code has become quite useful.

I find the feedback loop is much quicker with the unit tests I write, because I can see write away that the code is working or not without having to do much of anything.

So with being said, lets look and see how to setup the unit testing framework.

NodeJs

For my unit tests, I use Jasmine, Karma, Grunt which all sit on top of the NodeJs runtime, so for that you will first need to install NodeJS.

NodeJs comes with package installer called NPM. Similar to Gems in Ruby, or Nuget in Visual Studio, NPM will install all the packages needed to start unit testing.

Note, if you are starting a project from scratch, I would recommend installing Yoeman. Yoeman is a scaffolding package that will install a starter project with everything already configured.  For example, when I have a new AngularJs project, I use the Yoeman Angular Fullstack generator, and then go back in and finegle the generated code to my own preferences.

For this post I am assuming that the project and tests already exists. So I am going to only go though all the steps to to get up and running with unit testing on an existing project.

Also, I am running Windows 8.1, so if you are on a different OS like Linux or Apple OS, or even a different version of windows, these steps might differ slightly. I'm not really sure, but I had noticed that other posts were slightly different than what I had to do to get started.

Creating the package.json File

The first thing to do is create a package.json file. NPM uses this file to keep track of what you have installed and what versions of the packages you are using. The easiest way to create this file is to initialize NPM from the command line.

npm init

Doing this generates a file that will look like this.

 

You could also just manually create the file yourself. Either way, this file is required.

Installing the packages

You can install each package separately from the command line but an easier way to get everything installed is to get a copy of the packages.json file with all the packages you need and just type the following from the command line:

npm install

This command will take what ever you have in the package.json file and install it in your project if it isn't already installed.

 

My package.json file looks like this:

The packages under the "devDependencies" node tells NPM that these are packages are only for use in the development environment and are not to be copied to production.

You might also want to install Grunt, Karma and maybe even Yoeman globally so you don't have to keep installing it for every project. You can do that with the following commands.

npm install -g grunt-cli

npm install -g karma-cli

npm install -g yoeman

The "cli" suffix is the package that allows grunt and karma to called directly from the command line in Windows. The -g parameter tells NPM you want to install the package globally.

Initializing the karma.config.js File

Karma is a test runner developed by the AngularJs team. It's basically the engine that goes through all the unit test and runs them, and then provides the results of the executed unit tests. Once karma is installed, you will need a karma.config.js file to so karma knows things where the JavaScript files are located, what testing framework you want to use, etc.

You can generate a karma.config.js file by running the following command:

karma init

When you run this you will be asked a bunch of questions:

  • Which unit testing framework do you use?
  • Do you want to use Require.js?
  • Do you want to capture any browsers automatically?
  • What is the location of your source and test files?
  • Should any of the files included by the previous patterns be excluded?
  • Do you want karma to watch all the files and run the tests on change?

I typically accept all the defaults, and, if needed, go back and change the configuration later. My current file looks like this:

If you have separated your JavaScript framework files from your own custom JavaScript files, you will need to add what ever framework files you are using that are included in the tests. For example, I have included angular and angular-mocks for angular specific testing and I also have a reference to lodash.js.

Configuring Grunt

Gruntjs is a task runner that lets you run several tasks at once. For this demo, I am only running karma, but I could add other tasks like JsHint to check my JavaScript syntax, or Uglify to minimize files. Grunt needs a gruntfile.js file installed which tells grunt what tasks to run and how to run them.

My grunt file is pretty simple since I am only running one task. It looks like this:

   

Now I'm ready

Now that I have setup my Grunt file, and I have told Karma to watch my JavaScript files. Every time I make a change to JavaScript code and change it, Karma will run the test and provide me the results in the command window. I simply run "grunt" from the command line.

Running "karma:unit" (karma) task
[2014-06-24 11:14:00.421] [INFO] karma - Karma v0.12.16 server started at http://localhost:9876/
[2014-06-24 11:14:00.569] [INFO] launcher - Starting browser Chrome
[2014-06-24 11:14:04.015] [INFO] Chrome 35.0.1916 (Windows) - Connected on socket aX-CPdsznQq6Oi75cNhf with id 3608593
Chrome 35.0.1916 (Windows): Executed 19 of 19 SUCCESS (0.047 secs / 0.043 secs)


Conclusion

I think in future posts, I will discuss a little how I go about writing unit tests, but for now I'll leave you with this in the hope that at least gets you started in writing AngularJs unit tests.

If you have any questions or feedback, shoot me a comment I would glad to hear what you think?

 

JavaScript, Hoisting, Firefox, If/then Statements

Friday, March 21, 2014

Quick intro about JavaScript and Scoping

In most C and Java type languages a block (that is any curly brace) defines the scope of a variable or a function. However in JavaScript, scoping is at the function level. So when I define a variable inside a block (if/then statement for example) it can be used throughout the entire function it is in, including outside its defined block.

JavaScript will also take that function that is defined anywhere in a function and set its definition at the top of the function behind the scenes. This is called hoisting, and basically it allows you to call a function that is defined below the code you are calling it from.

 

So for example:

 

This works in all browsers because JavaScript hoisted the inner function to the top of the outer function behind the scenes.

If/Then statements and Firefox

The problem is in Firefox if you define a function inside an if/then statement the function no longer gets hoisted. This only happens in Firefox.

 

So in the following example, the following code works in IE and Chrome but is broken in Firefox.

 

In Firefox I get an error because it did not hoist the callHoistedFunction therefore it was not defined at the point it was being used.

ReferenceError: callHoistedFunction is not defined
var hello = callHoistedFunction();
 

So the moral of the story is never define a function inside a “if/then” or “try/catch” statement. As a matter of practice, you should probably just define all variables and functions at the top of the outer function as that is where it gets hoisted to anyways.

 

This is from Douglas Crockford’s book the “JavaScript, The Good Parts”. Pg 102.

 

In most languages, it is generally best to declare variables at the site of the first use. That turns out to be a bad practice in JavaScript, because it does not have block scope. It is better to declare all variables at the top of each function.

 

Here is his video on his book in case you were also interested.

http://www.youtube.com/watch?v=hQVTIJBZook

 

Hope this helps,