Angular2 in ASP.NET MVC Nuget Package

Standard

To install Angular2 Template for MVC & WebAPI, run the following command in the Package Manager Console

Install-Package Angular2-Template-for-MVC-and-WebAPI

This Nuget Package will help you to integrate Angular2 JS framework into ASP.NET MVC or WebAPI applications

Package includes ASP.NET MVC compatible tsconfig.json, typings.json, systemjs.config.js, package.json files. Package also includes client side JS libraries reference and configuration for Angular2, @angular/common, @angular/compiler, @angular/core, @angular/forms, @angular/http, @angular/platform-browser, core-js, lodash, rxjs, systemjs, zone.js. Package also contains sample SPA template implemented according to Angular2 Best Design Guidelines.

File Type INFO:

  1. File1: Package.json file
    package.json identifies npm package dependencies for the project.
    

    2. File2: tsconfig.json file

    This file defines how the TypeScript compiler generates JavaScript from the project’s files.
    

    3. File3: typings.json file

    This file provides additional definition files for libraries that the TypeScript compiler doesn’t natively recognize.
    

    Required Step: Install package.json file

    Open CMD and redirect to your application folder and Using npm from the command line, install the packages listed in package.json with the command:

      > npm install --save --save-dev
    

    wait for the installation to complete

    4. File4: systemjs.config.js file This file provides information to a module loader about where to find application modules, and registers all the necessary packages.

Project Usage:

  1. Folder name “App” in Scripts folder

    2. Application module file (App/app.module.ts)

    Angular itself is split into separate Angular Modules. This makes it possible for you to keep payload size small by only importing the parts of Angular that your application needs.Every Angular application has at least one module: the root module, named AppModule here.

    3. Component & add it to your application (App/app.component.ts)

    Every Angular application has at least one component: the root component, named AppComponent here.Components are the basic building blocks of Angular applications. A component controls a portion of the screen—a view—through its associated template.

    4. Start up file (App/main.ts)

    Now we need to tell Angular to start up your application.

    5. Index.cshtml in View Folders contain angular 2 directive

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

    6. _Layout.cshtml contain angular2 script reference and system.js startup configuration

     http://../../node_modules/core-js/client/shim.min.js
     http://../../node_modules/zone.js/dist/zone.js
     http://../../node_modules/reflect-metadata/Reflect.js
     http://../../node_modules/systemjs/dist/system.src.js
    
     <!-- 2. Configure SystemJS -->
     http://../../systemjs.config.js
     
         System.import('../../Scripts/App/main').catch(function (err) {
             console.error(err);
         });
     
    

Angular2: Creating custom sort filter pipe for datetime column ngFor directive

Standard

As you are aware of the fact that, Filters in Angular 1.x have been replaced with pipes in Angular2, most of the time we have datetime value in our array of objects(in easy terms dataset), so in order to display our data on front-end in the form of ASC/DESC datetime column, I have implemented a custom sorting pipe, please note that code is customized to handle both Ascending and Descending option

import { Injectable, Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'sortgrid'
})

@Injectable()
export class SortGridPipe implements PipeTransform {
    transform(array: Array<any>, args: string): Array<any> {
        if (typeof args[0] === "undefined") {
            return array;
        }
        let direction = args[0][0];
        let column = args.replace('-','');
        array.sort((a: any, b: any) => {
            let left = Number(new Date(a[column]));
            let right = Number(new Date(b[column]));
            return (direction === "-") ? right - left : left - right;
        });
        return array;
    }
}

You need to register the pipe within your module:

@NgModule({
 imports: [
   BrowserModule,
   HttpModule,
   FormsModule,
  ],
 declarations: [
   AppComponent,
   SortGridPipe
  ],
 providers: [
   All_Services
  ],
 bootstrap: [
   AppComponent
  ],
 schemas: [
   CUSTOM_ELEMENTS_SCHEMA
  ]
})

Html code:

<tr *ngFor="let item of mylst | sortgrid: '-createdDate'">
  <td>
      {{item.value}}
  </td>
  <td>
      {{item.createdDate}}
  </td>
</tr>
  • ‘-‘ sign with ‘-createdDate’ in above html code will sort data set in Descending manner.

Angular2: Creating custom search filter pipe for ngFor directive

Standard

As you are aware of the fact that, Filters in Angular 1.x have been replaced with pipes in Angular2, unfortunately, search filter for ng-repeat has been dropped in Angular2. So in order to select a subset of items from an array and returns it as a new array for the *ngFor directive, we have to create our own custom pipe.

import { Injectable, Pipe, PipeTransform } from '@angular/core';

@Pipe({
 name: 'searchfilter'
})

@Injectable()
export class SearchFilterPipe implements PipeTransform {
 transform(items: any[], field: string, value: string): any[] {
   if (!items) return [];
   return items.filter(it => it[field] == value);
 }
}

You need to register the pipe within your module:

@NgModule({
 imports: [
   BrowserModule,
   HttpModule,
   FormsModule,
  ],
 declarations: [
   AppComponent,
   SearchFilterPipe
  ],
 providers: [
   All_Services
  ],
 bootstrap: [
   AppComponent
  ],
 schemas: [
   CUSTOM_ELEMENTS_SCHEMA
  ]
})

Html code:

<input #txtFname placeholder="first name" />
<tr *ngFor="let item of mylst | searchfilter: 'fname' : txtFname.value">
  <td>
      {{item.fname}}
  </td>
  <td>
      {{item.lname}}
  </td>
</tr>

Angular2: Error – Cannot find name ‘many’ and namespace ‘_’ issues with Lodash in Angular2 application using Typescript

Standard

I have consumed lodash in previous project and blogged about it (link)

In the recent project when I updated lodash and typescript to their respective latest version. I start getting error in Visual Studio 2015.

Below is the list of error in VS:

Duplicate identifier '_'.
Cannot find name 'Partial'.
Cannot find namespace '_'.
A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
Cannot find name 'P'.
Cannot find name 'keyof'.
']' expected.
Cannot find name 'T'.
Declaration or statement expected.
A parameter initializer is only allowed in a function or constructor implementation.
Cannot find name 'T'.
']' expected.
')' expected.
Declaration or statement expected.
Cannot find name 'ConformsPredicateObject'.
Cannot find name 'Many'
Package.json:
{
  "name": "pms",
  "version": "1.0.0",
  "scripts": {},
  "license": "ISC",
  "dependencies": {
    "@angular/common": "^2.4.9",
    "@angular/compiler": "^2.4.9",
    "@angular/core": "^2.4.9",
    "@angular/forms": "^2.4.9",
    "@angular/http": "^2.4.9",
    "@angular/platform-browser": "^2.4.9",
    "@angular/platform-browser-dynamic": "^2.4.9",
    "@angular/router": "^3.4.9",
    "@angular/upgrade": "^2.4.9",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.10",
    "rxjs": "^5.2.0",
    "systemjs": "^0.20.9",
    "zone.js": "^0.8.0",
    "lodash": "^4.17.4"
  },
  "devDependencies": {
    "@types/core-js": "^0.9.37",
    "typescript": "^2.2.1",
    "typings": "^2.1.0",
    "@types/lodash": "^4.14.55"
  }
}

 

Solution:

Update @types/lodash in package.json to Typescript 2.0 compatible types in order to use lodash without any issue. Execute the below npm command

> npm install @types/lodash@ts2.0 --save-dev 
Updated Package.json:
{
  "name": "pms",
  "version": "1.0.0",
  "scripts": {},
  "license": "ISC",
  "dependencies": {
    "@angular/common": "^2.4.9",
    "@angular/compiler": "^2.4.9",
    "@angular/core": "^2.4.9",
    "@angular/forms": "^2.4.9",
    "@angular/http": "^2.4.9",
    "@angular/platform-browser": "^2.4.9",
    "@angular/platform-browser-dynamic": "^2.4.9",
    "@angular/router": "^3.4.9",
    "@angular/upgrade": "^2.4.9",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.10",
    "rxjs": "^5.2.0",
    "systemjs": "^0.20.9",
    "zone.js": "^0.8.0",
    "lodash": "^4.17.4"
  },
  "devDependencies": {
    "@types/core-js": "^0.9.37",
    "typescript": "^2.2.1",
    "typings": "^2.1.0",
    "@types/lodash": "ts2.0"
  }
}

Angular2: Resolve TypeScript TS2304 compilation errors in Visual Studio

Standard

I have recently updated my angular2 project and fell into this TS2304 error in Visual Studio 2015

Error    TS2304    Build:Cannot find name 'Promise'.   
Error    TS2304    Build:Cannot find name 'Map'.   
Error    TS2304    Build:Cannot find name 'Iterable'.   
Error    TS2304    Build:Cannot find name 'Set'.   
Error    TS2304    Build:Cannot find name 'Iterator'.
Package.json:
{
  "name": "pms",
  "version": "1.0.0",
  "scripts": {},
  "license": "ISC",
  "dependencies": {
    "@angular/common": "^2.4.9",
    "@angular/compiler": "^2.4.9",
    "@angular/core": "^2.4.9",
    "@angular/forms": "^2.4.9",
    "@angular/http": "^2.4.9",
    "@angular/platform-browser": "^2.4.9",
    "@angular/platform-browser-dynamic": "^2.4.9",
    "@angular/router": "^3.4.9",
    "@angular/upgrade": "^2.4.9",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.10",
    "rxjs": "^5.2.0",
    "systemjs": "^0.20.9",
    "zone.js": "^0.8.0"
  },
  "devDependencies": {
    "@types/core-js": "^0.9.37",
    "typescript": "^2.2.1",
    "typings": "^2.1.0"
  }
}
tsconfig.json:
{
  "compileOnSave": true,
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "typeRoots": [
      "node_modules/@types"
    ],
    "types": [
      "core-js"
    ]
  }
}
typings.json:
{
  "globalDependencies": {
    "core-js": "registry:dt/core-js#0.0.0+20160725163759",
    "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
    "node": "registry:dt/node#6.0.0+20160909174046"
  }
}

Solution 1:

If you want to stick to ES5 then then change types/core-js to version “0.9.36” in package.json.

"@types/core-js": "0.9.36",

Solution 2:

In case you want to use latest version of @types-core-js then you need to know that ES6 features like promises aren’t defined when targeting ES5. There are other libraries, but core-js is the javascript library that the Angular team uses. It contains polyfills for ES6. As you can see I have included @types in project, so simple solution is to change target from ‘es5’ to ‘es6’ or ‘es2015’

tsconfig.json:
{
  "compileOnSave": true,
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "typeRoots": [
      "node_modules/@types"
    ],
    "types": [
      "core-js"
    ]
  }
}

ASP.NET Core: Display more detailed information about the error after publishing project on Azure

Standard

After deploying ASP.NET CORE project on Azure, I start getting bunch of 500 internal errors for webapi’s, I investigated the failures in chrome dev tool and couldn’t find any detailed information there.

screenshot_4

The html response from server was:

screenshot_3

Solution:

So in-order to check out actual exception, I added couple of line in web.config file of project

<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false">
      <environmentVariables>
        <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
      </environmentVariables>
    </aspNetCore>

Yo can also add ASPNETCORE_ENVIRONMENT variable as App settings in Application Settings section of WebApp in Azure Portal.

screenshot_5

Angular2: Error – md-input-container must contain an mdInput directive. Did you forget to add mdInput to the native input or textarea element?

Standard

Error:

Error at MdInputContainerMissingMdInputError.ZoneAwareError 

md-input-container must contain an mdInput directive. Did you forget to
add mdInput to the native input or textarea element?

screenshot_2

Solution:

<md-input-container style="color: black;" class="pull-xs-left">
       <textarea [(ngModel)]="content" mdInput></textarea>
</md-input-container>

directive md-input needs to replaced with mdInput