JavaScript

Angular 2 Quickstart with ASP.NET Core

Updated version of this post can be found here.

After working with Aurelia over last couple of months it seemed prudent to try out Angular 2. This post is going to cover the installation of Angular 2 and launching a basic Angular 2 application from an ASP.NET Core (the new name for ASP.NET 5) controller. Make sure to check out the official quickstart guide here.

Installation

Open the package.json file and add the following dependencies and devDependencies. This project is using gulp and is using the typescript based version of the quickstart guide which is why the gulp and typescript references are there.

  "dependencies": {
    "angular2":"2.0.0-beta.1",
    "systemjs": "0.19.16",
    "es6-promise": "^3.0.2",
    "es6-shim": "^0.33.3",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.0",
    "zone.js": "0.5.10"
  },
  "devDependencies": {
    "gulp": "3.9.0",
    "gulp-concat": "2.6.0",
    "gulp-cssmin": "0.1.7",
    "gulp-uglify": "1.5.1",
    "gulp-typescript": "2.10.0",
    "rimraf": "2.5.0",
    "typescript": "1.7.5"
  }

If inside Visual Studio 2015 the proper packages will be restored when package.js is saved, but outside of Visual Studio open a command prompt to the same directory as the package.js file and run npm install  which will download the required packages.

Typescript Configuration

Next add a tsconfig.json file to the project. This file marks the root of a typescript project and contains configuration setting for that project. Details on configuration options can be found here.

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "system",
    "moduleResolution": "node",
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5"
  },
  "exclude": [
    "node_modules"
  ]
}

Angular 2 Bootstrap and Basic App

Create an Angular folder in the project’s root folder. Next add a app.component.ts file which is used to manage a view. This component is super simple and was pulled from the official quickstart guide.

import {Component} from 'angular2/core';

@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App</h1>'
})
export class AppComponent { }

Next add boot.ts which is used to bootstrap Angular 2.

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

bootstrap(AppComponent);

Gulp Tasks

This is the project that was the inspiration for the gulpjs introduction post. The first task is to move the Angular 2 dependencies from the node_modules folder to an Angular folder in wwwroot  so they will be available to be served.

gulp.task("angular2:moveLibs", function () {
    return gulp.src([
            "node_modules/angular2/bundles/angular2-polyfills.js",
            "node_modules/systemjs/dist/system.src.js",
            "node_modules/systemjs/dist/system-polyfills.js",
            "node_modules/rxjs/bundles/Rx.js",
            "node_modules/angular2/bundles/angular2.dev.js"
        ])
        .pipe(gulp.dest(paths.webroot + "Angular"));

});

The next task move the js files created by the typescript compiler when a ts file is saved from the Angular folder in the root of the project to wwwroot/Angular.

gulp.task("angular2:moveJs", function () {
    return gulp.src(["Angular/**/*.js"])
        .pipe(gulp.dest(paths.webroot + "Angular/app/"));

});

The last task just runs both of the previous tasks.

gulp.task("angular2", ["angular2:moveLibs", "angular2:moveJs"])

ASP.NET Controller

The Angular application is going to be run from the ASP.NET’s HomeController. Here is the new action that will load the yet to be created view.

public IActionResult Angular2()
{
    return View();
}

ASP.NET View

This is the view that when loaded kicks off the Angular 2 application. Add a new file called Angular2.cshtml in the Views/Home folder.  In the following first Angular related scripts are loaded. Then system.js is configured and the boot module is imported and the app is rendered inside of the my-app tag.

<html>
<head>
    <title>Angular 2 QuickStart</title>

    <script src="~/Angular/angular2-polyfills.js"></script>
    <script src="~/Angular/system.src.js"></script>
    <script src="~/Angular/Rx.js"></script>
    <script src="~/Angular/angular2.dev.js"></script>

    <script>
        System.config({
            packages: {
                '../Angular': {
                    format: 'register',
                    defaultExtension: 'js'
                }
            }
        });
        System.import('../Angular/app/boot')
              .then(null, console.error.bind(console));
    </script>

</head>

<body>
    <my-app>Loading...</my-app>
</body>

</html>

This is where the trouble started for me. It took a bit of searching, but the problem turned out to be with the system.js configuration. Since the view is in the HomeController it gets rendered out of as Home/Angular2.html and this project’s Angular files are up a directory so in order for system.js to find the Angular files the package configuration needed to be set to look up one folder.

This issue took longer to find than I would like to admit, but that is the danger is using libraries one is not familiar with. System.js was not my first thought since it was used in my Aurelia without issue. If you run into an issue check out the docs for system.js configuration.

Finally add the new view to main application’s nav bar. In Views/Shared/_Layout.cshtml add a link to Angular 2 on using the Home controller.

<div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
        <li><a asp-controller="Home" asp-action="Index">Home</a></li>
        <li><a asp-controller="Home" asp-action="Angular2">Angular 2</a></li>
        <li><a asp-controller="Home" asp-action="About">About</a></li>
        <li><a asp-controller="Home" asp-action="Contact">Contact</a></li>
    </ul>
    @await Html.PartialAsync("_LoginPartial")
</div>

Follow Up

This is a very basic Angular 2 application. Expect a follow up post in the new few weeks with this application build out more to utilize the same contacts web API as my Aurelia posts.

Update

If you are having issues upgrading beta 7 check out this post for a solution.

Angular 2 Quickstart with ASP.NET Core Read More »

Introduction to gulpjs

Working on a future blog post I hit some problems involving files that needed to be moved around as part of build process. This is one of the problems that gulp solves.

What is gulp?

Gulp is a task runner that utilizes node. The core idea behind task runners is automation. Have less that needs compiled into css, minified and output into the proper directory? That is a great use case for a task runner.

Gulp is not the only task runner out there. Grunt is another option and has actually been around longer. I am using gulp because it is the default in Visual Studio 2015. Google gulp vs grunt and decide which is right for you.

Installation

  1. Install node if needed from this site.
  2. From the console install gulp using npm install gulp -g

Project setup

Next add a gulpfile.js the root of the project where gulp is to be used. If using ASP.NET 5 this file will already exist and will include a few prebuilt tasks. If you are not using ASP.NET 5 the following is a mimimum gulpfile from the official getting started guide.

var gulp = require('gulp');

gulp.task('default', function() {
  // place code for your default task here
});

Also add gulp to the devDependencies section of the project’s package.json file. Since Visual Studio handles edits to package.json so nicely (intellisense and automatic package restore) I tend to edit the file manually instead of using npm.

 "devDependencies": {
    "gulp": "3.9.0"
  }

Plugins

The base gulp API only contains 4 functions (src, dest, task and watch) and doesn’t do a whole lot on its own. This is where plugins come in. Gulp has a ton of plugins that do all sorts of useful things. For example, the default gulpfile.js provided by Visual Studio has a min:js task that used gulp-concat and gulp-uglify to combine javascript files and then minify the result.

Example gulpfile for minification of javascript

The following is a full gulpfile based on the default file generated by Visual Studio stripped down to just the bits needed for the min:js task.

"use strict";

var gulp = require("gulp"),
    concat = require("gulp-concat"),
    uglify = require("gulp-uglify");

var paths = {
    webroot: "./wwwroot/"
};

paths.js = paths.webroot + "js/**/*.js";
paths.minJs = paths.webroot + "js/**/*.min.js";
paths.concatJsDest = paths.webroot + "js/site.min.js";

gulp.task("min:js", function () {
    return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
        .pipe(concat(paths.concatJsDest))
        .pipe(uglify())
        .pipe(gulp.dest("."));
});

The above will pull all the javascript files from wwwroot/js and its subfolders and combine them and output the results to site.min.js in the wwwroot/js folder.

Introduction to gulpjs Read More »