Click here to Skip to main content
14,022,522 members
Click here to Skip to main content
Add your own
alternative version

Stats

27.1K views
539 downloads
3 bookmarked
Posted 29 Jul 2016
Licenced CPOL

SharePoint REST API and AngularJs for 2013, 2016 and Online

, 2 Aug 2016
Rate this:
Please Sign up or sign in to vote.
This article is all about SharePoint and AngularJs and also handling HTTP requests like GET, POST, UPDATE, DELETE and file uploading using AngularJS in SharePoint 2013, 2016 and online.

Introduction

This sample contains a reusable angularjs module. The module contains a service and a directive. Anyone can use this module throw dependence injection. This is for those people who want to take the advantage of two way data binding in SharePoint client side development. In client side development, basically we make some GET, POST, UPDATE and DELETE request to some particular end-points. So this module will save you from code redundancy for making any HTTP requests. This module is applicable for content editor web part and SharePoint Hosted app development.

Before you begin

Target users require following knowledges before using this module. I am providing some references of those stuffs below.

  1. AngularJs
  2. REST API and SharePoint list
  3. SharePoint and AngularJs

Current problem

A typical GET request to get all lists looks like following.

function getAllLists() {

    $http({

        url: "/_api/web/lists"

            method: "GET",

        headers: {

            "accept": "application/json;odata=verbose",

            "content-Type": "application/json;odata=verbose"

        }

    }).success(function(result) {

        //do something here

    }).error(function(error, status) {

        // do something here

    });
}

And a GET request to get all items from a particular list looks like following.

function getAllItems() {

    $http({

        url: "/_api/web/lists/GetByTitle('List Title')/Items"

            method: "GET",

        headers: {

            "accept": "application/json;odata=verbose",

            "content-Type": "application/json;odata=verbose"

        }

    }).success(function(result) {

        //do something here

    }).error(function(error, status) {

        // do something here

    });
}

The purpose of these functions is different but they are sharing most of the code. So this module is taking all hassle of handling GET, POST, UPDATE and DELETE request. You will just pass your data and url to make any kind of request. Source code of this module is given below.

(function() {
    'use strict';

    angular.module('spNgModule', []).factory("spBaseService", spBaseService).directive("customFileChange", customFileChange);;

    spBaseService.$inject = ["$q", "$http", "IS_APP_WEB"];

    function spBaseService($q, $http, isAppWeb) {

        var baseUrl = isAppWeb ? _spPageContextInfo.webAbsoluteUrl : _spPageContextInfo.siteAbsoluteUrl;

        return {
            getRequest: getRequest,
            postRequest: postRequest,
            updateRequest: updateRequest,
            deleteRequest: deleteRequest,
            fileUploadRequest: fileUploadRequest,
            baseUrl: baseUrl
        };

        function getRequest(query, endPoint) {
            var deferred = $q.defer();
            $http({
                url: endPoint || baseUrl + query,
                method: "GET",
                headers: {
                    "accept": "application/json;odata=verbose",
                    "content-Type": "application/json;odata=verbose"
                }
            }).success(function(result) {
                deferred.resolve(result);
            }).error(function(result, status) {
                deferred.reject({
                    error: result,
                    status: status
                });
            });
            return deferred.promise;
        }

        function postRequest(data, url, endPoint) {
            var deferred = $q.defer();
            $http({
                url: endPoint || baseUrl + url,
                method: "POST",
                headers: {
                    "accept": "application/json;odata=verbose",
                    "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                    "content-Type": "application/json;odata=verbose"
                },
                data: JSON.stringify(data)
            }).success(function(result) {
                deferred.resolve(result);
            }).error(function(result, status) {
                deferred.reject({
                    error: result,
                    status: status
                });
            });
            return deferred.promise;
        }

        function fileUploadRequest(data, url, endPoint) {
            var deferred = $q.defer();
            $http({
                url: endPoint || baseUrl + url,
                method: "POST",
                processData: false,
                data: data,
                transformRequest: angular.identity,
                headers: {
                    "accept": "application/json;odata=verbose",
                    "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                    "Content-Type": undefined
                }
            }).success(function(result) {
                deferred.resolve(result);
            }).error(function(result, status) {
                deferred.reject({
                    error: result,
                    status: status
                });
            });
            return deferred.promise;
        }

        function updateRequest(data, url, endPoint) {
            var deferred = $q.defer();
            $http({
                url: endPoint || baseUrl + url,
                method: "PATCH",
                headers: {
                    "accept": "application/json;odata=verbose",
                    "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                    "content-Type": "application/json;odata=verbose",
                    "X-Http-Method": "PATCH",
                    "If-Match": "*"
                },
                data: JSON.stringify(data)
            }).success(function(result) {
                deferred.resolve(result);
            }).error(function(result, status) {
                deferred.reject({
                    error: result,
                    status: status
                });
            });
            return deferred.promise;
        }

        function deleteRequest(url, endPoint) {
            var deferred = $q.defer();
            $http({
                url: endPoint || baseUrl + url,
                method: "DELETE",
                headers: {
                    "accept": "application/json;odata=verbose",
                    "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                    "IF-MATCH": "*"
                }
            }).success(function(result) {
                deferred.resolve(result);
            }).error(function(result, status) {
                deferred.reject({
                    error: result,
                    status: status
                });
            });
            return deferred.promise;
        }
    }

    customFileChange.$inject = ["$parse"];

    function customFileChange($parse) {
        return {
            restrict: "A",
            link: function(scope, element, attrs) {
                var model = $parse(attrs.customFileChange);
                var modelSetter = model.assign;
                element.bind("change", function() {
                    scope.$apply(function() {
                        var reader = new FileReader();
                        reader.onload = function(e) {
                            var fileModel = {
                                fileName: element[0].files[0].name,
                                fileAsBuffer: e.target.result
                            };
                            modelSetter(scope, fileModel);
                        }
                        reader.onerror = function(e) {
                            alert(e.target.error);
                        }
                        reader.readAsArrayBuffer(element[0].files[0]);
                    });
                });
            }
        };
    }

})(window, document);

What's included in this module

  • getRequest(query, endPoint)
  • postRequest(data, url, endPoint)
  • updateRequest(data, url, endPoint)
  • deleteRequest(url, endPoint)
  • fileUploadRequest(data, url, endPoint)

endPoint is optional in everywhere. I will discuss the usages of it later on. You will be able to use these endpoints that support GET, POST, UPDATE and DELETE request. Every method will return you a promise and you will have to handle it in your code.

How to use 

At first, download this module from attachment. Attachment contains minified and non-minified version of my module. After downloading the file, add the reference in your project. For example, In SharePoint hosted App, It should look like following.

<script src="../Scripts/App/spNgModule.js"></script>

In Content Editor Web Part, you have to upload this file in some library then you will use it.

Adding dependence in your module

You can add this dependence in your module in following way. The name of this module is spNgModule.

(function () {
    angular.module("spNgModuleTest", ["spNgModule"])
    .constant("IS_APP_WEB", false);
})();

Here you will have to specify the value of IS_APP_WEB. It means which Web URL will be used for making GET, POST, UPDATE and DELETE request. After specifying the value of IS_APP_WEB, you will be able to use other URL also for making any request. That's why there is an optional parameter named endPoint

NB: If you specify endPoint in your request then url parameter will be optional. By default all requests will be made base on the value of IS_APP_WEB. Either it is APP Web or Host Web.

Injecting Service

The service name I have used is spBaseService. So you can inject this service in following way. 

angular.module("spNgModuleTest")
    .factory("spNgTestSvc", spNgTestSvc);

    spNgTestSvc.$inject = ["spBaseService"];

GET request example

spBaseService.getRequest(query, endPoint)

You can pass any query or end-point that support HTTP GET request. For example,

You want to get all lists under current site:

function getAllLists() {
    var query = "/_api/web/lists?$select=Title";
    return spBaseService.getRequest(query);
}

If you want get all items of a list, then it will be:

function getAllItems() {
    var query = "/_api/web/lists/GetByTitle('List Title')/Items";
    return spBaseService.getRequest(query);
}

If you want get all sub sites, then it will be:

function getSubSites() {
    var query = "/_api/Web/Webs";
    return spBaseService.getRequest(query);
}

So what I wanted to say by these examples is: Just to make any GET request, you will have to deal with query or endPoint.

Use of endPoint parameter

Someone may need endPoint in following scenario. 

Let's say your current site is https://xxx.sharepoint.com (can be host web or app web). Now you want to make a GET, POST, UPDATE or DELETE request to the sub site https://xxx.sharepoint.com/hr or a GET, POST, UPDATE or DELETE request to host web from the app web. In that case, you will need to use endPoint.

function getSubSites() {
    var endPoint = "https://xxx.sharepoint.com/hr/_api/Web/Webs";
    return spBaseService.getRequest(null, endPoint);
}

POST request example

It is applicable for adding new object (list item, file, site, document and so on). 

spBaseService.postRequest(data, url, endPoint)

data is the quest body. It will vary from request to request. For example, to add a sub site, the request body should look like:

var data = {
    parameters: {
        __metadata: {
            'type': 'SP.WebInfoCreationInformation'
        },
        Url: "site url",
        Title: "site title",
        Description: "site description",
        Language: 1033,
        UseUniquePermissions: true
    }
};

url is the any end-point that supports POST request. For adding a sub site, the end-point is 

var url = "/_api/web/webinfos/add";

Usages of endPoint can be found  here.

So the full POST request of adding a site is:

function addSubSite() {
    var data = {
        parameters: {
            __metadata: {
                'type': 'SP.WebInfoCreationInformation'
            },
            Url: "site url",
            Title: "site title",
            Description: "site description",
            Language: 1033,
            UseUniquePermissions: true
        }
    };
    var url = "/_api/web/webinfos/add";
    return spBaseService.postRequest(data, url);
}

UPDATE request example

spBaseService.updateRequest(data, url, endPoint);

It is all most same as POST request. You can use this method to update any object in your site. Have a look on the updating an item in a particular list.

function updateItemById(itemId) {
    var url = "/_api/web/lists/GetByTitle('List Name')/GetItemById(" + itemId + ")";

    var data = {
        __metadata: {
            type: "SP.Data.SpNgListListItem"
        },
        Title: "New sp ng item updated " + Math.random()
    };
    return spBaseService.updateRequest(data, url);
}

See here the usages of endPoint.

DELETE request example

spBaseService.deleteRequest(url, endPoint);

You will use this method to remove something from your site. Let's say we want to remove an item having ID equals 5.

function deleteAnItem() {
    var url = "/_api/web/lists/GetByTitle('List Name')/GetItemById(5)";
    return spBaseService.deleteRequest(url);
}

See here the usages of endPoint.

File upload example

spBaseService.fileUploadRequest(data, url, endPoint);

In request body, you will have to pass the file as ArrayBuffer. As I said earliar, this module also contains a directive so this directive will help you to get file as ArrayBuffer. The name of this directive is customFileChange. The html for uploading should look like

<input type="file" data-custom-file-change="attachment" /> 

attachment is the model and it will give you the file as ArrayBuffer. You can change its name as per your liking. There are two properties you will get from this model such as fileName and fileAsBuffer.

Following is the example of uploading an attachment of a partcular item having ID equals 2.

function uploadAttachment(attachment){
            var url = "/_api/web/lists/GetByTitle('SpNgList')/items(2)/AttachmentFiles/add(FileName='" + attachment.fileName + "')";
            return spBaseService.fileUploadRequest(attachment.fileAsBuffer, url);
        }

See here the usages of endPoint.

Handling response example

You will get a promise in return from all of the above methods. So it is same as typical response handling angular code. For example

spNgTestSvc.addSubSite()
    .then(function(successResponse) {
        // code after success
    }, function(errorrResponse) {
        //code after error
    });

errorResponse has two properties such as error and statuserror is the actual error object returned by SharePoint end-point.

Conclusion

That's all about my current module. I will try to make it more better in future updates. As my source is opened so I will be highly pleased if I get any feedback and suggestion from my readers.

License

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

Share

About the Author

Atish Dipongkor
Instructor / Trainer Jashore University of Science and Technology
Bangladesh Bangladesh
2016 Microsoft MVP

Currently, I am devoted to provide technical and development support to the SharePoint clients and also I am working on angularjs. I am experienced with C#, ASP.NET, SharePoint, SignalR, angularjs, MS SQL, Oracle 11g R2, Windows Phone, Firefox OS and so on. I have fallen in love with many technologies but never got married to any of them. I am evolving myself as full stack developer. I always like to share knowledge as much as to gather from you.

You may also be interested in...

Comments and Discussions

 
QuestionI cannot do it work Pin
Walter Di Biase4-Oct-18 8:02
memberWalter Di Biase4-Oct-18 8:02 
QuestionBower facility, Pin
prince_ppy15-Jul-17 23:30
memberprince_ppy15-Jul-17 23:30 
QuestionQuestion Pin
Member 1291586021-Dec-16 1:39
memberMember 1291586021-Dec-16 1:39 
AnswerRe: Question Pin
Atish Dipongkor25-Dec-16 22:34
professionalAtish Dipongkor25-Dec-16 22:34 

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
Web06 | 2.8.190417.4 | Last Updated 3 Aug 2016
Article Copyright 2016 by Atish Dipongkor
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid