Build a SharePoint Add-In with Angular2 and TypeScript

Scot Hillier

by Scot Hillier on 1/27/2016

Share this:
Print

Article Details

Date Revised:
1/27/2016

Applies to:
Angular 2, ECMAScirpt5, ES2015, javascript, Node Package Manager, NPM, SharePoint Add-in, SharePoint app, TypeScript, Visual Studio 2015


With the release of Angular 2 beta, I have been working to create samples for all the various SharePoint development techniques. As part of this series, I have already posted articles on creating an Office add-in and embedding Angular 2 into SharePoint pages. I’m going to continue the series with this article by showing how to create a simple SharePoint add-in. You can find the complete solution in the IT Unity GitHub repository.

In the first two articles, I used Angular 2 beta directly with JavaScript libraries and references. These samples are good for understanding the basic Angular 2 architecture, however, it’s not the way that you’ll develop large-scale enterprise applications. Because Angular 2 is based on ES2015 syntax – but browser support for ES2015 is not complete – your apps will require the use of several polyfills and shims. Furthermore, some aspects of ES2015 – like the JavaScript loader standard – aren’t complete and may change over time. All of this can lead to significant difficulties in using the JavaScript libraries directly.

When you want to create significant applications with Angular 2, you should use TypeScript. TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Microsoft built support for TypeScript right into Visual Studio 2015 and you can easily add TypeScript to projects built with other tools. TypeScript provides a level of abstraction that makes it possible to write your application using ES2015 syntax that compiles into ECMAScript5. That means that you can create Angular 2 apps today that run on any platform in any browser. As standards change over time, a new version of the TypeScript compiler is all you need to make your existing TypeScript code run.

For this article, I am going to use Visual Studio 2015 to create the SharePoint add-in. I know that many developers like to use Visual Studio Code these days, but Visual Studio 2015 has excellent SharePoint and Office development tools that I want to use. My goal is to have the best SharePoint tooling available while also having access to new capabilities like the Node Package Manager (NPM), which I will use to get the required Angular 2 framework libraries. I am also choosing to create a SharePoint-hosted add-in because the security plumbing is minimal for this type of add-in, which means I can concentrate on the development process. I’ll dig into security in later articles.

It’s all about the plumbing

The greatest barrier to writing SharePoint add-ins with Angular 2 and TypeScript is setting up your project in Visual Studio 2015. So, I’m going to walk through the process in a little more detail than I might normally do for an article. I am going to assume, however, that you have built a SharePoint add-in before so I don’t have to repeat well-understood concepts.

Generating the new project

You first want to create the new SharePoint add-in project. For this part, there is no difference between a standard SharePoint add-in and one based on Angular 2. Simply create a new App for SharePoint project as you normally would. For this article, I will create a SharePoint Online site, but the process will also work with an on-premises site.

Once you have created the new project, you’ll want to clean up some of the auto-generated artifacts. In particular, you should remove the jQuery library from the project and delete the app.js file from the Scripts node. I suggest that you remove the jQuery library using the NuGet Package Manager, which presents a button for uninstalling the library as shown in Figure 1.

Use NuGet Package Manager to remove the jQuery library from your new project.
Figure 1, Uninstalling jQuery

Adding TypeScript support

Next, you want to add TypeScript support to your project. Visual Studio supports TypeScript files generally, but it also supports the use of a TypeScript configuration file within the project to create “virtual TypeScript projects”, which are like a project within your project. I have worked through several different approaches for supporting TypeScript, and I think using a configuration file is the best approach.

You can add the configuration file by right-clicking the project and selecting Add>New Item from the context menu. While Visual Studio has a built-in TypeScript Configuration File item, it does not appear in the Add New Item dialog when you are working on a SharePoint add-in. As a result, you have to add a json file to your project named tsconfig.json. Figure 2 shows how to search for the JSON file type and name it correctly. When you have added the json file, you can replace its contents with those shown in Listing 1.

Searching for JSON file type in Visual Studio 2015
Figure 2, Adding the TypeScript configuration file

Listing 1, TypeScript configuration

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

Listing 1 shows the proper TypeScript configuration to support the SharePoint add-in. You can read about all the options here, but the important ones for this discussion are: target, module, and outDir. The target setting specifies the version of ECMAScript to which TypeScript will compile. In this case, I want ECMAScript5 to guarantee the widest-possible browser support. The module setting specifies the external module pattern to be generated. You can use any of the popular module patterns, but ECMAScript2015 is adopting the System module pattern (a.k.a, ‘register’ format), so that is how TypeScript should be configured. The outDir setting specifies that the compiled files should be placed in the scripts folder, which will allow the SharePoint project to add them to the solution package for distribution.

In Listing 1, you’ll also notice the presence of an exclude setting for the node_modules folder. I haven’t added the folder yet, but I will when I bring in the required Angular 2 libraries. The exclusion setting ensures that TypeScript will not try to compile anything in that folder.

Adding required libraries

Once TypeScript support is configured, you can add the required supporting libraries. The Angular 2 team distributes all of the required libraries through NPM. NPM is a package distribution system similar to NuGet. Eventually someone may put the Angular 2 libraries into NuGet, but for now NPM is the only way to get them. Fortunately, Visual Studio 2015 supports NPM through a command prompt, which you can launch by searching for Node.js Command Prompt. In the command prompt, change directory to the root of your SharePoint project. Then install libraries using the following command:

npm install angular2 systemjs es6-promise es6-shim rxjs

All of the packages will be placed under a folder named node_modules. However, you won’t actually see that folder in the Solution Explorer. That’s because the packages get added in the background. If you click Show All Files in the Solution Explorer, you can see the folder is excluded from the project as shown in figure 3. Don’t attempt to include the files in your project! It’s not necessary to include the files for the TypeScript compiler to work. Furthermore, Visual Studio will crash if you try.

Installed Angular 2 files are in a hidden folder named node_modules
Figure 3, The hidden node_modules folder

Coding the SharePoint add-in

After the project is properly setup, you can finally start to code the SharePoint add-in. Because you are going to work in TypeScript but distribute JavaScript, you’ll need a folder to separate the TypeScript files from the JavaScript files. The simplest approach is just to create an app folder in the root of the project. You will add your TypeScript files to this folder, but they will compile into the scripts folder for distribution.

Add your first TypeScript file by right-clicking the app folder and selecting Add>New Item. In the Add New Item dialog, add a new TypeScript file named app.module.ts. Figure 4 shows how the operation appears in the Add New Item dialog. After you add the file, immediately set the Deployment Type property to NoDeployment. Remember, the TypeScript files are for design time only – you don’t actually want to distribute them to SharePoint. Figure 5 shows the property setting for the file.

Adding a TypeScript file in the Add New Item dialog
Figure 4, Adding a TypeScript file

Set the Deployment Type property for your TypeScript files to NoDeployment. You don't want to distribute them to SharePoint. Figure 5, Setting TypeScript file properties

For this sample, the app.module.ts file is a simple class that provides some text. This class is a placeholder for more advanced operations such as CSOM or REST calls, but I want this article to focus on the fundamentals. Future articles will focus more on advanced services. Listing 2 shows the code for the file.

Listing 2, A simple class

export class Welcome {
    public static getMessage() {
        return 'Hello, World!';
    }
}

Once you save the TypeScript file in Visual Studio, the underlying JavaScript file will be compiled. However, the file will be hidden. In order to distribute the JavaScript file, you must include it in the project. So, click Show All Files in the Solution Explorer and add the generated JavaScript file to the scripts node for distribution. Follow this process for each new TypeScript file you add to the project. If you want to support debugging, add the map file as well. Figure 6 shows the file in the Solution Explorer.

The JavaScript file, compiled from the TypeScript file, included for distribution in your SharePoint add-in
Figure 6, Adding the JavaScript file for distribution

The main component in the application is a TypeScript file named app.component.ts. This component imports the first module along with the core Angular 2 functionality and outputs a value to the HTML page Document Object Model (DOM). Listing 3 shows the code. As with the first TypeScript file, be sure to change the deployment setting and include the generated JavaScript in the scripts node.

Listing 3, The main component

import {Welcome} from './app.module'
import {Component} from 'angular2/core'

@Component({
    selector: 'app-main',
    template: `<h1>${Welcome.getMessage()}</h1>`
})

export class AppComponent { }

The last component to add is a file named boot.ts that will bootstrap the entire application. The bootstrap component is used to configure the Angular 2 framework and then load the main component. Listing 4 shows the code. Once again, be sure to change the deployment setting and include the generated JavaScript in the scripts node.

Listing 4, The bootstrap component

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

Once the coding is complete, you can update the default.aspx file to include the appropriate library references and launch the app. You can simply replace all the references in the PlaceHolderAdditionalPageHead with the code in Listing 5. The code in Listing 5 uses the System loader to load the bootstrap component, which configures the Angular 2 framework, and then calls the main component.

Listing 5, Setting script references

<script src="https://cdnjs.cloudflare.com/ajax/libs/
             es6-shim/0.33.3/es6-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/
             systemjs/0.19.16/system-polyfills.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/angular2-polyfills.js"></script>
<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/Rx.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/angular2.dev.js"></script>
<script>
    System.config({
        packages: {
            '../scripts': {
                format: 'register',
                defaultExtension: 'js'
            }
        }
    });
    System.import('../scripts/boot')
          .then(null, console.error.bind(console));
</script>

The last thing to do is replace the content in PlaceHolderMain placeholder with the selector used by the main component. The content generated by the main component will be placed into the selector. Simply replace all the content in PlaceHolderMain with the following.

<app-main></app-main>

Testing the app

Once the coding is completed, you should be able to run the app directly from Visual Studio. As with any SharePoint-hosted app, Visual Studio will launch the browser and open the target SharePoint site you specified when creating the project. If successful, you’ll see the message shown in figure 7. If you have trouble, make sure that all the TypeScript files and the tsconfig.json file are all marked NoDeployment, then clean the project and try again. Deployment of the add-in will fail if any of the design-time files are marked for distribution.

Your SharePoint add-in, created with TypeScript, compiled to JavaScript, running in Visual Studio
Figure 7, The running app


Topic: Development

Sign in with

Or register

  • bandar judi bola
  • Hi Scott,

    Thanks for the wonderful article, it is definitely a stepping stone for angular2 into SharePoint.
    However, I''''m having issues in getting this work in SP 2013. No matter what, my component is not getting loaded and i''''m stuck with the message "Loading...". Any help is appreciated.
    Thanks
  • Hello,

    I built your SharePoint/Angular2 Typescript solution and have two issues and a general question:
    1) Typescript doesn''''t generate the JS file on build or save. I use tsc -w from node.js
    2) The app deploys but doesn''''t show the "Hello World Line".
    3) Is this app project available to download?
    Thanks,
    Howard
  • when targeting es5 How to get rid of Angular2 errors on Cannot find map, Promise ...
    if I target es6 the errors will go away, but I must target es5 to support old browsers.
  • Hi Scot, my compliment for your interesting article however I had a problem with the compiling of typescript files (during the save), to solve this I added the property "compileOnSave": true, in the tsconfig file and after that I have seen the javascript file in the Script folder.
  • Same as John Guilbert, not work in IE11. Error " ''''System'''' is undefined ". I guess it is related with system.js, but no answer after search google. Any idea?
  • Works fine in Chrome and Firefox, but not in IE 11. Any ideas....I do see there has been an IE fix js file, but didn''''t fix issue when added script in.
  • some xml tags were stripped out, they are ES5
    False
    system
    False
    True
    ./Scripts
    True
    True
    False
    True
    True
    node
    system
  • I am using Visual Studio 2015 Update 2. In the SharePoint app project, I modified the project file to include "
    ES5
    False
    system
    False
    True
    ./Scripts
    True
    True
    False
    True
    True
    node
    system



    "
    And I also downloaded packages to node_modules using npm install command.
    now I can compile the TypeScript to javascript, but it complaints that it can't find [email protected]/core, cannot find name "Promise", "Map" etc. feel like I am pretty close to get it work, but still missing a small step, please advise , Thanks
  • I had LOTS of issues getting the plumbing just right, but the following worked for me:

    * Add tsc to the Pre-Build Command as stated below:
    "via the Project Properties > "Build Events" tab > in the box "Pre-build event command line" the line "tsc"

    * Change "target" in tsconfig.json to "ES6"
  • This is great!
    One question though,
    I have an existing custom action that fires javascript:getKeyDocsPDFFile();
    So how do I make an angular2 component that will be triggered by this?
    Is it enough to have a method named "getKeyDocsPDFFile()" ?
    Thank you in advance
  • I like this article. It is very clear. However, as angular2-rc 1.0 released, they changed the project setting. So, can you update your article using angular2-rc 1.0?
  • These errors are pretty much exactly what they say. Whenever I get these errors, it means that I didn't get all the required packages from NPM.
  • Excellent post Scott. This helps us a lot. Thanks a ton.

    I am facing issue when I add code "import {Component} from 'angular2/core'" or any import from angular files. When I try to save the file VS is promting "Project contains errors. Output generation is skipped." When I checked errors tab all errors are from virtual project created for type script and for Typescript files in node_modules folder.

    Severity Code Description Project File Line Suppression State
    Error TS2304 Cannot find name 'Promise'. TypeScript Virtual Projects c:\\Users\\user\\documents\\visual studio 2015\\Projects\\SharePointApp\\SharePointApp\\node_modules\\rxjs\\observable\\FromObservable.d.ts 7 Active
    Error TS2304 Cannot find name 'Promise'. TypeScript Virtual Projects c:\\Users\\user\\documents\\visual studio 2015\\Projects\\SharePointApp\\SharePointApp\\node_modules\\rxjs\\observable\\PromiseObservable.d.ts 9 Active
    Error TS2304 Cannot find name 'Promise'. TypeScript Virtual Projects c:\\Users\\user\\documents\\visual studio 2015\\Projects\\SharePointApp\\SharePointApp\\node_modules\\rxjs\\observable\\PromiseObservable.d.ts 10 Active
    Error TS2304 Cannot find name 'MapConstructor'. TypeScript Virtual Projects c:\\Users\\user\\documents\\visual studio 2015\\Projects\\SharePointApp\\SharePointApp\\node_modules\\angular2\\src\\facade\\collection.d.ts 1 Active
    Error TS2304 Cannot find name 'Map'. TypeScript Virtual Projects c:\\Users\\user\\documents\\visual studio 2015\\Projects\\SharePointApp\\SharePointApp\\node_modules\\angular2\\src\\core\\change_detection\\differs\\default_keyvalue_differ.d.ts 23 Active
    Error TS2304 Cannot find name 'Map'. TypeScript Virtual Projects c:\\Users\\user\\documents\\visual studio 2015\\Projects\\SharePointApp\\SharePointApp\\node_modules\\angular2\\src\\core\\change_detection\\differs\\default_keyvalue_differ.d.ts 25 Active
    Error TS2304 Cannot find name 'Map'. TypeScript Virtual Projects c:\\Users\\user\\documents\\visual studio 2015\\Projects\\SharePointApp\\SharePointApp\\node_modules\\angular2\\src\\core\\change_detection\\parser\\locals.d.ts 3 Active


    • I had the same issue using VS2015 update 2. It compiled when I toggled from es5 to es6 and then back again. Seems like the virtual typescript project is very "Brittle".
  • I spent forever trying to get the TypeScript files to generate the JavaScript files in the Scripts folder. Enabling "Automatically compile Typescript files which are not part of a project" in Tools > Options did not work for me as the post stated below. After doing some research blogs were saying tsconfig.json are not supported in VS 2015 Update 1 for some project types. I then added via the Project Properties > "Build Events" tab > in the box "Pre-build event command line" the line "tsc". Then and only then were the TypeScript JavaScript files generated in the Scripts folder. Also I was getting a lot of errors to the effect that "Promise" was missing so in the boot.ts file I add this reference path ///
  • That sounds right because the approach creates a virtual TypeScript project within the SharePoint add-in project.
  • To get the compilation from TypeScript to JavaScript working with Visual Studio 2015 Update 1, I had to check "Automatically compile Typescript files which are not part of a project" in Tools > Options> Text Editor > TypeScript > Project
  • Checkout Listing 1. Notice the module flag is there. If you don't get the virtual TypeScript project setup correctly, Visual Studio will default to using it's own settings, which are in the project file itself and visible in the project properties. I found this approach to be difficult because Angular 2 needs very specific settings. Bets to use a tsconfig.json as I do in the exercise.
  • hi, could you tell me anything about the error "Cannot compile external modules unless the '--module' flag is provided."