Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 Beta: Visual Studio ASP .NET MVC

I built an application for Angular 2 alpha 45 and it worked wonderfully, but I had to 'mess' around a lot to get it to work. I understand Angular 2, but I don't understand how to get it to work to start actually using Angular 2.

I am trying a clean build of the 'Angular 2: 5 min Quickstart'. There are a number of issues, and I am going to be as specific as possible. I want to learn why these issues are occurring and hopefully how to fix them. Visual Studio 2015 Update 1, Typescript 1.7.

Typescript Configuration: the quickstart includes a tsconfig.json file.

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

I am not sure if this does anything though, as I had to edit the ProjectName.csproj file and add the line: <TypeScriptExperimentalDecorators>True</TypeScriptExperimentalDecorators> to get rid of the Experimental Decorators Error. https://github.com/Microsoft/TypeScript/issues/3124 seems to suggest the tsconfig file needs to be in /Scripts to work, but that doesn't work for me either.

I would like to know either how to get this tsconfig file to work, or to edit the .csproj file to get the same compiler options. If you look in the Project Properties > Typescript Build. Are these what matter? Should the module system be: System?

My file structure is the same as the Quickstart.

app/
    app.component.ts
    boot.ts
node_modules/
    blah
index.html
tsconfig.json
package.json

I used powershell to run npm install to get everything in the node_modules directory.

import {Component} from 'angular2/core'; displays an error. ../node_modules/angular2/core'; doesn't display the error, but then when you build the project, you get lots of build errors in files in node_moduels/angular2/src/*. Now, I might be able to go in and manually fix these issues, but I feel like the configuration is wrong if these errors are appearing. The tsconfig seems to want to exclude node_modules. Why am I not able to use 'angular2/core' and instead must use a relative path to it? If I include the node_modules in the Visual Studio project, there are an insane amount of build errors in the node_modules. Separately: I am doing this clean build because I couldn't work out how to update the project from alpha 45 to beta 0. Fixing bugs in my project from Angular 2 changes will be easy, but getting the app to load all the modules at the moment is impossible.

The next part is assuming I get past the build errors: In index.html there is the:

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

I have never gotten the System.import('app/boot') to work without specifying the file extension. Is this a visual studio issue or is it a .NET MVC issue? If I specify the file extension in index.html, then I get 404s with System.js trying to find the component files without a file extension (even though the config has defaultExtension: 'js'. Is this because I need to include the js files in my project? Then if I get past that issue, I have to deal with

system.src.js:1049 GET http://localhost:63819/angular2/http 404 (Not Found)

I didn't have a single build error, but now System.js is not loading anything.

I feel like these are all issues that are created by different systems interpreting the typescript differently. I feel like I haven't been clear, but I don't know how to be clear about this issue. I would really appreciate any help and guidance you could bestow upon me. I feel like I have been searching for an answer to this for days now.

like image 490
Adam Hitchens Avatar asked Dec 16 '15 19:12

Adam Hitchens


People also ask

Can we use Angular with ASP.NET MVC?

To load Angular in ASP.NET MVC, include the script references of Angular core modules and Syncfusion JavaScript asset files in _Layout file , and load the component in index. cshtml like the following code snippets.

Why Angular is better than ASP.NET MVC?

Growing libraries and extensions. Single-page applications, and Angular in particular, are constantly being updated with more and more presentation libraries and extensions compared to ASP.NET MVC. Angular provides robust extensibility and customization and has deep community support that is continually growing.

Is MVC or Angular better?

Both ASP.NET MVC and AngularJS has their own purposes and advantages. As with your specific question, AngularJs is better for SPA (Single Page Applications), where as ASP.NET MVC is a full fledged server side Application which can contain WebAPIs, Routing engine as well as HTML emitting Views.

Can you use Angular with ASP NET?

The ASP.NET Core with Angular project template provides a convenient starting point for ASP.NET Core apps using Angular and the Angular CLI to implement a rich, client-side user interface (UI).


3 Answers

I've had some issues at the beginning too, but they're mostly easy to fix.

TsConfig equivalent

First, the project setup:

<TypeScriptToolsVersion>1.7.6</TypeScriptToolsVersion>
<TypeScriptModuleKind>system</TypeScriptModuleKind>
<TypeScriptExperimentalDecorators>true</TypeScriptExperimentalDecorators>
<TypeScriptEmitDecoratorMetadata>true</TypeScriptEmitDecoratorMetadata>
<TypeScriptAdditionalFlags> $(TypeScriptAdditionalFlags) --experimentalDecorators </TypeScriptAdditionalFlags>
<TypeScriptAdditionalFlags> $(TypeScriptAdditionalFlags) --emitDecoratorMetadata </TypeScriptAdditionalFlags>

System module is right, but check that it's properly included in your html file. You can also pick it in your project options window.

Depending on your VS version, you need to specify the flags in additional flags (older versions) or in the dedicated tags. You still need to check sourcemaps and es target version in your project options (es5 is EcmaScript 5 in EcmaScript version, obviously).

Don't forget to install the latest TypeScript version, otherwise RxJs won't work.

Angular2 files

While downloading angular2 via npm makes sense, I wouldn't include node_modules directly in your typescript folder. Including the whole folder means taking every other node module along, like gulp for instance. Instead, you can simply copy the whole angular2 folder in your typescript directory, in the Content folder (you can do this automatically with gulp or a simple bat file if you want).

About the typescript errors, the issue is that Visual Studio will try to analyze all files in your angular2 folders, and some of those files are duplicated. You need to remove the sources and keep only the compiled js files and the type definitions. That means:

  • remove /es6 (they're the files used to develop in es6 instead of typescript)
  • remove /ts (the source files)
  • remove bundles/typings (additionnal defintion files for es6-shim and jasmine)

You need the rxjs folder at the same folder level as angular2, otherwise the includes won't work, ie :

Content  
    typings  
        angular2  
        rxjs  
        mymodule
           whatever.ts
        boot.ts

In your html files, you can link the js files in the bundle folders of both angular2 and rxjs.

<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="/content/typings/angular2/bundles/angular2-polyfills.js"></script>
<script src="/content/typings/rxjs/bundles/Rx.min.js"></script>
<script src="/content/typings/angular2/bundles/angular2.dev.js"></script>
<script src="/content/typings/angular2/bundles/router.dev.js"></script>

Then your imports will look like this :

import { Component } from 'angular2/core';

System configuration

To make the imports work, you need to configure System. The configuration is fairly simple :

        System.paths = {
            'boot': '/content/typings/boot.js',
            'mymodule/*': '/content/typings/myModule/*.js'
        };
        System.config({
            meta: {
                'traceur': {
                    format: 'global'
                },
                'rx': {
                    format: 'cjs'
                }
            }
        });
        System.import('boot');

Include this code after the script tags for angular and all your other librairies.

Since Angular2 is included globally (via the script tags), you don't need to add it to the System configuration. Then in your files, you can import your modules this way :

import { MyThing } from "mymodule/whatever";
like image 194
Camille Wintz Avatar answered Sep 22 '22 08:09

Camille Wintz


If you're up and running with npm install fetching your dependencies into node_modules, here's how to use them there in-place without having to move them into a /lib or /scripts directory, or change the way you write your typescript files from the way shown in the Quickstart:

Project Properties -> TypeScript Build

For "Module System", Select "System":

enter image description here

Set TypeScript compiler options

If using ASP.NET Core, set options in tsconfig.json:

{  
    "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
 },
 "exclude": [
    "node_modules"
 ]
}

If you are using ASP.NET (Non-Core), set the compiler options in the csproj file. (Docs for setting compiler options: https://github.com/Microsoft/TypeScript/wiki/Setting-Compiler-Options-in-MSBuild-projects) In a text editor find the PropertyGroup with the other TypeScript options and add in:

<TypeScriptExperimentalDecorators>True</TypeScriptExperimentalDecorators>
<TypeScriptEmitDecoratorMetadata>True</TypeScriptEmitDecoratorMetadata>
<TypeScriptModuleResolution>node</TypeScriptModuleResolution>

Load Source files in the correct order

In your index.html, set up your scripts in this specific order to ensure that modules are loaded from the node_modules folder (you have to load rxjs and angular2 bundles after doing System.config otherwise the system loader will download the angular/rxjs source files again since it didn't register them with the right path)

<!-- load system libraries -->
<script src="~/node_modules/es6-shim/es6-shim.min.js"></script>
<script src="~/node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="~/node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="~/node_modules/systemjs/dist/system.js"></script>

<!-- configure system loader first -->
<script>
    System.config({
        defaultJSExtensions: true,
        paths: {
            'angular2/*': 'node_modules/angular2/*',
            'rxjs/*': 'node_modules/rxjs/*'
        }
    });
</script>

<!-- load app bundles *after* configuring system so they are registered properly -->
<script src="~/node_modules/rxjs/bundles/Rx.js"></script>
<script src="~/node_modules/angular2/bundles/angular2.js"></script>

<!-- boot up the main app -->
<script>
    System.import("app/main").then(null, console.error.bind(console));
</script>

App TypeScript can use the standard import syntax, here's app/main.ts:

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

Note the angular2 "import" doesn't need to have '../node_modules/' prepended because the TypeScript compiler's module resolution is using "node" mode. (docs on node module resolution logic: https://github.com/Microsoft/TypeScript/issues/2338) Hope that works for you!

like image 25
Marcus L Avatar answered Sep 22 '22 08:09

Marcus L


I am generally happy with new things with asp.net 5 vnext and Angular 2. But rigging up Angular 2 in Visual Studio has been a hassle. I followed the angular.io quickstart guide religiously and had no luck getting a the Hello Angular 2 app running, until I used the following code:

<script src="~/lib/anguar2/angular2-polyfills.js"></script>
<script src="~/lib/es6-shim/es6-shim.js"></script>
<script src="~/lib/systemjs/system.js"></script>
<script>

    System.config({
        defaultJSExtensions: true
      
    });

</script>
<script src="~/lib/rxjs/rx.js"></script>
<script src="~/lib/anguar2/angular2.min.js"></script>
<script>
    System.import('js/boot');
</script>

I wish I had a better understanding of why this works, and the angular boilerplate doesn't. But at least I got it working. Hope this helps.

like image 45
brando Avatar answered Sep 19 '22 08:09

brando