Click here to Skip to main content
14,163,580 members
Click here to Skip to main content
Add your own
alternative version

Stats

20.3K views
256 downloads
10 bookmarked
Posted 22 Feb 2016
Licenced CPOL

SharePoint App using TypeScript and AngularJS

, 6 Jul 2016
Rate this:
Please Sign up or sign in to vote.
How to create a SharePoint App with TypeScript and Angular Js

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 defines the type of the member variable and function parameters. The type will be removed while translating 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 is 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.

var a:number = 3;                            var a = 3;
var b:string = 'abc';                        var b = 'abc';

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 the same as namespace in C#, to avoid the name collisions and get the functionality of IIFE.

Typescript with Module

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 definitely file using Nuget Package Manager.

Verify the typescript option available in project properties:

If the typescript option missed, follow the steps:

Unload the project:

Edit the project and include the lines:

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

Save and reload the project.

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

///<reference path="project.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 minified. 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 what 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

///<reference path="projectservice.ts" />
module App.Controller {

    export class ProjectCtrl {
        public projects: Array<App.Model.Project>
        public project: App.Model.Project;

        static $inject = ['ProjectService'];
        constructor(private projectService: App.Service.ProjectService) {
            this.project = new App.Model.Project();
        }
        public getProjects(): void {
            this.projectService.getProjects().then(data => {
                this.projects = data.data.d.results;
                console.log(this.projects);
            }).catch(e => {
                alert('Error' + e);
            });
        }

        public addProject(): void {
            this.projectService.addProject(this.project).then(data => {
                this.getProjects();
                this.project = new App.Model.Project();
            }).catch(e => {
                alert('Error' + e);
            });
        }
    }
}

App.ts

///<reference path="../scripts/typings/angularjs/angular.d.ts" />
///<reference path="../scripts/typings/angular-ui-router/angular-ui-router.d.ts" />
///<reference path="project/projectctrl.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]);
}

Build the project and combine TS file.

Build and include the test.js and test.map file in project.

Open the element.xml, remove 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="App">
    <File Path="App\test.js" Url="App/test.js" ReplaceContent="TRUE" />
    <File Path="App\test.js.map" Url="App/test.js.map" ReplaceContent="TRUE" />
  </Module>
</Elements>
<html>
<head>
    <link rel="Stylesheet" type="text/css" href="../Content/App.css" />
    <script src="../Scripts/jquery-1.9.1.js"></script>
    <script src="../Scripts/angular.js"></script>
    <script src="../Scripts/angular-ui-router.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>

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Krishna KV
Team Leader Aspire Systems
India India
Having 7+ years of experience in IT Industry and having Masters Degree in Information Technology.

Personal Blog : http://krishna-kv.blogspot.in/

You may also be interested in...

Pro

Comments and Discussions

 
Question$injector:modulerr Pin
bobk54427-Jun-16 2:01
memberbobk54427-Jun-16 2:01 
AnswerRe: $injector:modulerr Pin
Krishna KV6-Jul-16 20:53
memberKrishna KV6-Jul-16 20:53 
Generalnice Pin
Aswin Arun5-Mar-16 5:44
memberAswin Arun5-Mar-16 5:44 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun2-Mar-16 20:15
memberHumayun Kabir Mamun2-Mar-16 20:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03 | 2.8.190518.1 | Last Updated 7 Jul 2016
Article Copyright 2016 by Krishna KV
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid