SharePoint Pals
 | Sign In
Creating a SharePoint App with TypeScript and Angular Js - Step by Step
by Krishna KV 21 Feb 2016
Author
Team Leader, Aspire Systems
Visits   
Today  :   10     Total  :    9752

In this article we can see how to create a SharePoint App with TypeScript and Angular Js. Before diving deep into the SharePoint App development part, lets start with a brief introduction to Type Script and why it is required.

What is Typescript

  • It adds Static Typing and structuring (class, modules, etc..) to JavaScript.
  • Type Annotations
  • Static type checking
  • Type Definitions
  • Compile-time checking
  • Open Source
  • Supported by angular2

Strongly typed

Typescript define the type of the member variable and function parameters. The type will be removed while translation to JavaScript. It enables the compiler to catch type error at compile time and provides IDE intellisense.

Javascript

Typescript

 function test(a ,b ) {
      return a*b;
 }
 
 alert(test('one','two'))
 function test(a:number,b:number):number{
 	return a*b;
 }
 alert(test(10,20));
 

Complier

The code we write in TypeScript is compiled into JavaScript and map file. Map file used to map the JavaScript and TypeScript file lines to debug TypeScript.

Compile: tsc test.ts à test.js

While compiling the TypeScript code into JavaScript, type annotations are removed.

image

DefinitelyTyped

The DefinitelyTyped adds definitions for the existing many JavaScript libraries in the form of interfaces.

· Describes the types defined in the external libraries (d.ts)

· Not Deployed only used for development purpose

· It is used to check the types

Alternatives

• Dart

• CoffeeScript

• ClojureScript

• Fay

Module & Export keyword

Modules are same as namespace in C#, to avoid the name collisions and get the functionality of IIFE.

image

Typescript with Module

image

To make the internal aspects of the module accessible outside of the module we need to declare with export keyword, As the model and service are accessed by the angular controller we used the keyword export.

Create a sharepoint Hosted App and the necessary typescript definitley file using Nuget Package Manger.

image

To active the typescript complier If missing

image

Unload the project

image

Edit the project and include the lines

 <PropertyGroup>
     <TypeScriptSourceMap>true</TypeScriptSourceMap>
   </PropertyGroup>
 <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" />
 

image

Save and reload the project.

image

Include the DefinitelyTyped by Package manager console

· Install-Package angularjs.TypeScript.DefinitelyTyped

Project.ts

   module App.Model {
 
                     export class Project {
                         public Title: string;
                        public  Id: number;
                       public  Client: string;
         
                     }
                 }

ProjectService.ts

 module App.Service {
             export class ProjectService {
 
                 static $inject = ['$http'];
                 constructor(private $http: ng.IHttpService) {
                 }
 
                 public getProjects(): ng.IPromise<any> {
                     var url = App.Config.appWebUrl + "/_api/SP.AppContextSite(@target)" +
                         "/web/lists/getbytitle('Projects')/items?$select=Title,ID,Client&" +
                         "@target='" + App.Config.hostUrl + "'";
                     console.log(url);
                     return this.$http({
                         method: 'GET',
                         url: url,
                         headers: { "Accept": "application/json; odata=verbose" }
                     });
                 }
 
                 public addProject(project: App.Model.Project): any {
                     console.log($("#__REQUESTDIGEST").val());
                     var data = {
                         __metadata: { 'type': 'SP.Data.ProjectsListItem' },
                         Title: project.Title,
                         Client: project.Client
                     };
                     var url = App.Config.appWebUrl + "/_api/SP.AppContextSite(@target)" +
                         "/web/lists/getbytitle('Projects')/items?" + "@target='" + App.Config.hostUrl + "'";
                     return this.$http({
                         url: url,
                         method: "POST",
                         headers: {
                             "Content-Type": "application/json;odata=verbose",
                             "Accept": "application/json;odata=verbose",
                             "X-RequestDigest": $("#__REQUESTDIGEST").val()
 
                         },
                         data: data
                     });
                 }
             }
         }

$Inject

Without injecting the program works well until the Js gets Minifed. The minification process will probably alter the names of the parameters and it results in unknown inject of the Angular.

The $inject is a special property of AngularJS to determine that what are the services need to be injected at runtime. It should be marked as static and it is an array of string. The order of the array string and the constructor parameter should be matched.

ProjectCtrl.ts

 module App.Service {
             export class ProjectService {
 
                 static $inject = ['$http'];
                 constructor(private $http: ng.IHttpService) {
                 }
 
                 public getProjects(): ng.IPromise<any> {
                     var url = App.Config.appWebUrl + "/_api/SP.AppContextSite(@target)" +
                         "/web/lists/getbytitle('Projects')/items?$select=Title,ID,Client&" +
                         "@target='" + App.Config.hostUrl + "'";
                     console.log(url);
                     return this.$http({
                         method: 'GET',
                         url: url,
                         headers: { "Accept": "application/json; odata=verbose" }
                     });
                 }
 
                 public addProject(project: App.Model.Project): any {
                     console.log($("#__REQUESTDIGEST").val());
                     var data = {
                         __metadata: { 'type': 'SP.Data.ProjectsListItem' },
                         Title: project.Title,
                         Client: project.Client
                     };
                     var url = App.Config.appWebUrl + "/_api/SP.AppContextSite(@target)" +
                         "/web/lists/getbytitle('Projects')/items?" + "@target='" + App.Config.hostUrl + "'";
                     return this.$http({
                         url: url,
                         method: "POST",
                         headers: {
                             "Content-Type": "application/json;odata=verbose",
                             "Accept": "application/json;odata=verbose",
                             "X-RequestDigest": $("#__REQUESTDIGEST").val()
 
                         },
                         data: data
                     });
                 }
             }
         }

App.ts

 module App {
 
     export class Config {
         private static manageQueryStringParameter(paramToRetrieve: string): any {
             var params =
                 document.URL.split("?")[1].split("&");
             var strParams = "";
             for (var i = 0; i < params.length; i = i + 1) {
                 var singleParam = params[i].split("=");
                 if (singleParam[0] == paramToRetrieve)
                     return singleParam[1];
             }
         }
 
         public static appWebUrl: string;
         public static hostUrl: string;
 
         static $inject = ["$stateProvider", "$urlRouterProvider"];
 
         public static loadConfig(): void {
             Config.appWebUrl = decodeURIComponent(this.manageQueryStringParameter("SPAppWebUrl"));
             Config.hostUrl = decodeURIComponent(this.manageQueryStringParameter("SPHostUrl"));
         }
 
     }
 
     var main = angular.module('projectApp', ['ui.router']);
     App.Config.loadConfig();
     main.controller('ProjectCtrl', App.Controller.ProjectCtrl);
     main.service('ProjectService', ['$http', '$q', App.Service.ProjectService]);
 }

image

Select Show all files in solution explorer and include the test.js and test.map file.

image

Open the element.xml in the app folder remove all the .ts file path and include the test.js and test.map file.

 <?xml version="1.0" encoding="utf-8"?>
 <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <Module Name="Pages">
     <File Path="Pages\Default.aspx" Url="Pages/Default.aspx" ReplaceContent="TRUE" />
   </Module>
 </Elements>

Default.aspx

 <html>
 <head>
     <link rel="Stylesheet" type="text/css" href="../Content/App.css" />
     <script src="../Scripts/angular.js"></script>
     <script src="../App/test.js"></script>
 </head>
 <body>
     <form runat="server">
     </form>
     <h1>Project </h1>
     <div ng-app="projectApp">
         <div ng-controller="ProjectCtrl as vm">
             <div style="float: left; border: 1px solid gray;">
                 <table ng-init="vm.getProjects()">
                     <tr>
                         <td>SNO</td>
                         <td>Project</td>
                         <td>Client</td>
                     </tr>
                     <tr ng-repeat="project in vm.projects">
                         <td>{{$index+1}}</td>
                         <td>{{project.Title}}</td>
                         <td>{{project.Client}}</td>
                     </tr>
                 </table>
             </div>
             <div>
                 <table>
                     <tr>
                         <td>Project</td>
                         <td>
                             <input type="text" ng-model="vm.project.Title" /></td>
                     </tr>
                     <tr>
                         <td>Client</td>
                         <td>
                             <input type="text" ng-model="vm.project.Client" /></td>
                     </tr>
                     <tr>
                         <td colspan="2">
                             <button ng-click="vm.addProject()">Add Project</button></td>
                     </tr>
                 </table>
             </div>
         </div>
     </div>
 </body>
 </html>
blog comments powered by Disqus

SharePoint Pals

Pals
SharePoint Pals, a community portal for SharePoint developers, Administrators and End Users. Let's join hands and share the point together.
Read this on mobile

Training

Angular Js Training In Chennai
Advanced Angular Js training with real world developer scenarios
Angular Js, Web Api and Ionic for .Net Developers
All in one client side application development for .Net developers
Angular Js For SharePoint Developers
Get ready for the future. Its no more just C#

Get Connected

SharePoint Resources

SharePoint 2013 and 2010 Web Parts
Free Web Parts with Source Code for SharePoint Community




SharePoint 2013 Books and Tutorials
Collection of free SharePoint 2013 books and tutorials (eBooks, pdfs)

Supported By

Contribute your article and be eligible for a one month Free Subscription for Plural Sight. The Author of the most popular New Article (published in the previous month) will be awarded with a Free One month Plural Sight Subscription. Article can be sent to articles@sharepointpals.com in a word document.

Related Resources

Recent Tweets

Twitter January 15, 00:25
How To Enable Target Value And Actual Value In #D3 Gauge Chart https://t.co/VxSi4QnNrC

Twitter January 15, 00:24
How To Open #SharePoint List Hyperlink Column In Modal #Popup Window https://t.co/EQ7HkoZDkX

Twitter January 15, 00:24
Quick Introduction To #Asp.NetCore And It’s Features https://t.co/zAXObHCFpH

Twitter January 15, 00:22
How To Configure #PerformancePoint Services To Use Secure Store In #SharePoint 2013 https://t.co/LEwnUoI7EY

Twitter January 15, 00:21
How To Block Or Disable #Office365 Services https://t.co/Yvp2VPFIRP

Follow us @SharePointPals
Note: For Customization and Configuration, CheckOutRecent Tweets Documentation