Quantcast

comments edit

The source repository for this article is on Github.

This series sample will convert the Tour of heroes sample application from angular.io.

Getting things up and running

Starting from part 1, getting the first part of the tutorial to work was mainly copy and paste job from Hero editor.

I also updated package.json to use latests versions of libs (Angular2 version 2.0.0-beta.8), but ran into a typescript compilation issue :

Compiling...
### Fast Compile >>src/ts/app.component.ts
### Fast Compile >>src/ts/boot.ts
Using tsc v1.7.3
GitHub/Samples.Angular2/Samples.Front/node_modules/angular2/platform/browser.d.ts(77,90): error TS2304: Cannot find name 'Promise'.
GitHub/Samples.Angular2/Samples.Front/node_modules/angular2/src/core/application_ref.d.ts(83,60): error TS2304: Cannot find name 'Promise'.
GitHub/Samples.Angular2/Samples.Front/node_modules/angular2/src/core/application_ref.d.ts(83,146): error TS2304: Cannot find name 'Promise'.
... and so on ...

This was easily fixed, thanks to http://stackoverflow.com/a/35514492/971, just edit boot.ts to reference the typings !

// from : http://stackoverflow.com/a/35514492/971
/// <reference path="../../node_modules/angular2/typings/browser.d.ts" />

import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';

bootstrap(AppComponent);

And everything is now running fine !

Adding the next parts

Adding the Master/details and Multiple components was also a quick copy/paste story.

As I didn’t lile having the css and html hardcoded into the components, I took the opportunity to move them to their own files :

@Component({
    selector: 'my-app',
    moduleId: module.id,
    templateUrl: 'app.component.html',
    styleUrls: ['app.component.css'],
    directives: [HeroDetailComponent]
})

Here you can see a moduleId property. This one is used to not have to hardcode the ‘app’ (module name) in the template and style urls. However, due to an issue with relativeUrl and SystemJS I had to create a shim.d.ts file and reference it in main.ts :

// from : https://github.com/angular/angular/issues/6053
declare var module: any;

Finally, I split the hero module into its own directory, as I like having things neatly organised.

comments edit

The source repository for this article is on Github.

Building your first Angular2 app using Visual Studio 2015 is quite simple. Let’s have a look at what’s inside a simple hello world app.

This sample is based on angular.io quickstart, by adapting it to run on Visual Studio 2015. Following are some key points.

package.json

As explained in angular.io quickstart, dependencies are required to run the angular application. Differences between dependencies and devDependencies are explained in depth here.

The main dependencies are Angular2 (sure…) and systemjs. The latter is a dynamic module loader, removing all the hassle of referencing all your application js files in the index.html.

Other dependencies are polyfills, providing functionnality that will be offered later by browsers (hopefully). Internet Explorer has it’s own set of required shims, which have to be included in a specific order in index.html.

gruntfile

Like in previous samples, I’m using a gruntfile for managing the development and build process :

  • copy files into wwwroot
  • copy dependencies into wwwroot/vendor
  • compile typescript sources into wwwroot/app
  • watch for changes in typescript or html files, and copy them to wwwroot

The dependencies to copy are specified manually in the gruntfile. This may seem complicated to injector/wiredep fans, but at the moment I did not find an easier way to do it. Proposals will be appreciated !

application sources

The html and other static files are located in a src/html folder, and get copied to wwwroot folder. The application code is located in src/ts folder and get compiled into wwwroot folder using grunt-ts task.

It may seem easier to put everything in wwwroot directly, but separating the sources will enable for later testing of release building of application, including sources in unit test runner, and so on.

what are the main differences with AngularJS 1.5, from this hello world point of view ?

  • Angular2 is now based on typescript
  • There is no attribute based bootstrapping of your application, a root component is now used.
  • Systemjs is used for managing modules (webpack can be used as well).

Next part in this series will convert the Tour of heroes sample application from angular.io.

comments edit

The source repository for this article is on Github.

In this part I’ll continue automating testing, with protractor integration. This is straightforward but requires a little plumbing configuration!

NPM packages used

Add the following packages to the package.json file :

  • grunt-protractor-runner
  • grunt-contrib-connect

The key packages here are grunt-contrib-connect, and grunt-protractor-runner. The grunt-protractor-runner package version 3.0.0 relies on nodejs version 4.0 at least.

Hopefully the update is easy : go to the node website, download the latest version, and make Visual Studio use it, in Tools > Options > Projects and Solutions > External Web Tools, and add the path to nodejs on top.

Visual studio config

Connect grunt task

Create a new task in gruntfile.js for starting the connect web server, which will serve your application to protractor runner.

connect: {
	server: {
		options: {
			port: 9001,
			base: 'wwwroot'
		}
	}
},

Protractor grunt task

The protractor task needs to update the webdrivers and start them in standalone mode (this is easier to setup)

protractor: {
	run: {
		options: {
			configFile: "test/protractor.conf.js",
			webdriverManagerUpdate: true
		}
	}
}

The e2e task, which will start the connect web server, and run protractor tests.

grunt.registerTask('test:e2e', [
	'connect:server',
	'protractor:run'
]);

And finally the protractor configuration file, with 2 important points :

exports.config = {
	// not required in standalone mode
	// seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['e2e/scenarios.js'],
    baseUrl: 'http://localhost:9001',
    rootElement: '[ng-app]'
}

Running this task will produce the following in task runner explorer console :

Protractor runner

comments edit

The source repository for this article is on Github.

In this part I’ll dive into unit testing your AngularJS code. Not so much on the test specs details, as there are enough documentation on those. I’ll show how to set up a nice workflow which will set up tests as they’re added, and run them automatically when you edit you javascript code, and create code coverage reports.

NPM packages used

Add the following packages to the package.json file :

  • grunt-contrib-watch
  • grunt-karma
  • karma
  • karma-chrome-launcher
  • karma-coverage
  • karma-ie-launcher
  • karma-jasmine
  • karma-phantomjs-launcher
  • phantomjs

The key packages here are grunt-contrib-watch, grunt-karma and karma-coverage.

Watch task

Create a new task in gruntfile.js for reacting on file change events. This will trigger injection of JS files, or test running.

watch: {
	// adding or removing a js file trigger injections
	injections: {
		files: ['<%= paths.app %>/app/**/*.js'],
		tasks: ['wiredep', 'injector'],
		options: {
			event: ['added', 'deleted'],
		},
	},
	
	// changing an application file triggers automated tests
	tests: {
		files: ['<%= paths.app %>/app/**/*.js'],
		tasks: ['karma:unit']
	}
},

Karma grunt task

The karma task is quite simple as well, this one has two sub-tasks, to run unit tests into phantomjs, reporting results in a console; or runs tests directly into IE and Chrome browsers.

karma: {
    allBrowsers: {
        configFile: 'test/karma.conf.js',
        browsers: ['Chrome', 'IE']
    },
    unit: {
        configFile: 'test/karma.conf.js',
        browsers: ['PhantomJS']
    },
}

Will produce the following in task runner explorer console :

Karma runner

Code coverage

Producing code coverage reports is also simple, just add the relevant reporters, preprocessors and plugins to the karma.conf.js file.

reporters: ['progress', 'coverage'],

// process application files (not test !) for coverage
preprocessors: { '../wwwroot/app/**/!(*.spec).js': ['coverage'] },

plugins: [
	'karma-jasmine',
	'karma-chrome-launcher',
	'karma-ie-launcher',
	'karma-phantomjs-launcher',
	'karma-coverage'
],

And see output in test/artifacts/coverage-html folder :

Code coverage

HTML test runner

Finally, should you want to debug your tests, you can add the Jasmine html runner to the project, and inject JS files into it.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Jasmine Spec Runner v2.3.4</title>
    <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.3.4/jasmine_favicon.png">
    <link rel="stylesheet" href="lib/jasmine-2.3.4/jasmine.css">
    <script src="lib/jasmine-2.3.4/jasmine.js"></script>
    <script src="lib/jasmine-2.3.4/jasmine-html.js"></script>
    <script src="lib/jasmine-2.3.4/boot.js"></script>
    <!-- bower:js -->
    <!-- endbower -->
    <!-- injector:js -->
    <!-- endinjector -->
</head>
<body>
</body>
</html>

Then you can just run it from the file system :

Html runner

comments edit

The source repository for this article is on Github.

Front end development capabilities saw a huge boost with the release of Visual Studio 2015 and the seamless integration of Npm, Grunt and Bower. In the first part of this series I’ll summarize quickly how to get started creating an AngularJS and ASP.NET 5 WebApi application. First of all, you’ll need the following tools:

Then, create a new web application project using the ASP.NET 5 Templates :

Creating an ASP.NET 5 project

Add an index.html file inside the wwwroot folder.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <p>Hello</p>
</body>
</html>

This folder will be the root of your application, from the web server point of view. Press F5 and, behold :

Creating an ASP.NET 5 project

project.json

This file is used for defining your ASP.NET 5 application dependencies and other properties. Here a dependency on Microsoft.AspNet.IISPlatformHandler and Microsoft.AspNet.StaticFiles is sufficient.

Then you can add three main files:

  • The package.json manages development dependencies: the various tools to process source files during the build process.
  • The bower.json manages application dependencies: all libraries and frameworks that your application depends on.
  • The gruntfile.js file is handling frontend application development build process. For example, watching for scss file changes to generate css, and minify javascript files for production deployment.

package.json

Add a dependency to grunt, injector, and wiredep. Injector and wiredep are used to modify your html files to include bower dependencies and your application source code.

bower.json

Add a dependency to angular, ui-router, and jquery. After saving, Visual Studio should start downloading those. Semantic versioning is used, and nicely explained here on StackOverflow

gruntfile.js

Here is a bit more work, add a wiredep and injector tasks. Wiredep is used for bower dependencies, and injector is used for application files.

injector: {
    options: {
        lineEnding: "\r\n", // this is a Windows centric sample ;)
        relative: true, // relative to injection target file
        addRootSlash: false
    },

    // application scripts injection sub-task
    appScripts: {
        files: {
            '<%= paths.app %>/index.html': [
                '<%= paths.app %>/app/**/*.module.js',
                '<%= paths.app %>/app/**/*.js',
                '!<%= paths.app %>/app/**/*.spec.js'
            ]
        }
    },

    // application css injection sub-task
    appCss: {
        files: {
            '<%= paths.app %>/index.html': [
                '<%= paths.app %>/styles/**/*.css'
            ]
        }
    }
},

wiredep: {
    app: {
        src: [
            '<%= paths.app %>/index.html'
        ]
    }
}

Both tasks will inject file references into your index.html, which will need adaptation :

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>

    <!-- bower:css -->
    <!-- endbower -->
    <!-- injector:css -->
    <!-- endinjector -->
</head>
<body>

    <!-- bower:js -->
    <!-- endbower -->
    <!-- injector:js -->
    <!-- endinjector -->

    <p>Hello</p>
    <div ng-app="app">
        <ui-view />
    </div>
</body>
</html>

Finally, add an angularjs controller inside an app folder :

(function () {
    'use strict';

    angular.module('app', [
        // Angular modules 

        // Custom modules 
        'app.home',

        // 3rd Party Modules
        'ui.router'
    ])
    .config(function ($urlRouterProvider, $stateProvider) {
        // For any unmatched url, redirect to /home
        $urlRouterProvider.otherwise("/home");
        // Now set up the states
        $stateProvider
            .state('home', {
                url: "/home",
                templateUrl: "app/app.template.html",
                controller: "HomeController",
                controllerAs: "home"
            });
    })
    .controller('HomeController', HomeController);

    function HomeController() {
        var vm = this;
        vm.title = 'Hello world';
    };
})();

And run both wiredep and injector tasks from task runner :

Task runner