Migrating a TypeScript application from ASP.Net MVC to Angular2 – Lessons Learned

To evaluate Angular2, I started to convert a TypeScript application hosted in an ASP.Net MVC application to be hosted by the Angular framework.

The application continuously polls data from a web service, performs a couple of calculations, and displays the calculated results. It is a display-only auto-paging application – the only user interaction being to allow for manual paging. Parts of the display are updated by requesting a PartialView and adding it to the display using jQuery append().

Getting started is quite easy:

  • download, install, and configure Visual Studio Code
  • download and install node.js
  • create application directory and configuration files, and run npm install


First, we need to translate MVC Controllers and Views into Angular2 @Component classes and templates:

A page (controller+view) typically translates into a component with an associated HTML template.

Depending on your application, a PartialView may also be represented by a component. It may also translate into a part of a template being activated by NgSwitch or NgIf.

The file app/app.component.ts defines the URL routes, with @RouteConfig being the equivalent of MVC routing configuration. Each page you can directly address by a URL in a browser needs to be added to the @RouteConfig declaration.

Angular Exceptions

During development, you will occasionally meet the error condition 

The selector “my-app” did not match any elements

Currently, the only reliable way for me to resolve the condition is to close the browser window, restart npm lite-server, and hitting ctrl-F5.

Unfortunately, this was not the only (recurring) exception generated by the Angular2 framework. True, this is still a beta version (15), but if an exception in the framework occurs, there is almost no way of debugging it, as developers are used to debug their code. There is simply too much magic happening in the background. I repeatedly had to remove code or html and re-insert it step by step to figure out which part of the code caused a framework exception. And judging from browsing through GitHub issues, the situation has improved considerably from earlier versions.

Coding and Legacy Code

If your component needs to process URL parameters, there is the built-in routeParams.get() method. There is no automatic mapping of URL parameters to model class properties, but I developed a simple TypeScript function which will provide this convenience.

Adding and referencing existing TypeScript code to an Angular2 application is straight-forward. As I wanted to keep changes to existing code to a minimum, I simply added the scripts in the main index.html page using <script> tags.

However I found that Angular2 does not render <script> elements inside HTML templates. Fortunately, this code can be moved to and thus accessed from the @Component class, either in its constructor or one of the component’s lifecycle hooks, the Angular equivalent of ASP.Net events.

Angular2 uses import to load and reference TypeScript code. To reference code loaded by a <script> tag, you need to declare external symbols, as is typical for TypeScript’s .d.ts files.

To implement calls from the legacy code into the Angular2 code, I needed to store the Angular component in a window property, and access this property to invoke a method of that component:

// myComponent.ts:
constructor() {
  (<any>window).myComponent = this;
methodCall() {
// legacy.ts

Just a tiny change. Alternatively, every referenced declaration (and their dependencies) would have needed to be marked as export.

Comparing Architecture and TypeScript Hosting in ASP.Net MVC and Angular2

Comparing Architecture and TypeScript Hosting in ASP.Net MVC and Angular2

Dynamic Views

To dynamically render additional views, I created another component and assigned it a selector. The parameters displayed in the dynamic view are stored in a class, and the main component stores an array of this class:

export class MySubView {
  ... members ...

In the main component:

public subviews: MySubView[] = [];

In the main component’s HTML template:

<mysubview *ngFor="#subview of subviews" [data]="subview"></mysubview>

The sub component is declared as

 selector: 'mysubview'
export class MySubViewComponent {
  @Input() data: MySubView;

A new mysubview item is simply created by Angular2 by adding an object to the array:

this.subviews.push(new MySubView(...parameters..));

If a component needs to dynamically switch between several available templates, things get a bit complicated, but it’s feasable.

Disabling some Angular2 features

Angular2 allows CSS styles per @Component, and when rendering a component’s CSS, adds a component-specific attribute to the HTML elements, as well as to their CSS declarations.

Since I did not want to edit my CSS (which would have certainly made the CSS declarations cleaner and more specific), I deactivated this CSS magic by declaring the component

encapsulation: ViewEncapsulation.None,

Also, I wanted to disable Angular’s data-binding mechanism, since my legacy code takes care of all data-binding, and I wanted to avoid any interference between the two.

Adding the component declaration

changeDetection: ChangeDetectionStrategy.OnPush

switches change detection and auto-updates off.


Starting with Angular2 certainly comes with a learning curve. Switching platforms, even though they are comparable, may be a major effort. Whereas my little sample just concerned hosting existing functionality in Angular2, adapting existing code as a “real” Angular2 application – designing and using components, CSS handling, data-binding and change detection – is probably an effort similar to writing the application from scratch.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: