CRUD operations on SharePoint list using AngularJS

In this post, I am going to share some code snippets for performing CRUD operation on a SharePoint list using only client side script written with AngularJS.

It is a simple implementation, where I am going to create a web part, which will have reference to a controller that will read, create, update and delete list items.

I hope you are reading this post with some prior experience with SharePoint and AngularJS. The environment I am working upon is a SharePoint Online (Office 365) site.

I have created a Contacts list as in the below screenshot.


For this example, I will be using only 3 fields/columns in the list.
ID (Auto generated for every item in the list)
Last Name (Internal name: Title)
First Name (Internal name: FirstName)

Create the webpart

I have added one Content Editor Webpart to a page and linked it to our view page [listItems.html].



The view page has 4 sections to view contacts, add, edit and delete them. For each of these operations, I have created 4 separate controllers. Below is the code for the same.


<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <script type="text/javascript" src="/sites/ListOps/Scripts/jquery.min.js"></script>
    <script type="text/javascript" src="/sites/ListOps/Scripts/angular.min.js"></script>
    <script type="text/javascript" src="/sites/ListOps/Scripts/listItems.controller.js"></script>
    
    <style type="text/css">
        .Table {
            display: table;
        }

        .Row {
            display: table-row;
        }

        .Cell {
            display: table-cell;
            padding: 5px;
        }
    </style>
</head>
<body>
    <h3>View Contacts</h3>
    <hr />
    <div ng-app="spApp">
        <div ng-controller="viewItemsController">
            <div ng-repeat="contact in contacts">
                {{contact.ID}}: {{contact.Title}}, {{contact.FirstName}}
                <br />
            </div>
        </div>
        <hr />


        <h3>Add Contacts</h3>
        <div ng-controller="addItemsController">
            <div class="Table">
                <div class="Row">
                    <div class="Cell">
                        First Name :
                    </div>
                    <div class="Cell">
                        <input type="text" id="firstName" ng-model="firstName" />
                    </div>
                </div>
                <div class="Row">
                    <div class="Cell">
                        Last Name :
                    </div>
                    <div class="Cell">
                        <input type="text" id="lastName" ng-model="lastName" />
                    </div>
                </div>
                <div class="Row">
                    <div class="Cell">
                        
                    </div>
                    <div class="Cell">
                        <input type="button" id="btnAddContact" value="Add Contact" ng-click="addContact()" />
                    </div>
                </div>
            </div>
        </div>
        <hr />


        <h3>Edit Contacts</h3>
        <div ng-controller="editItemsController">
            <div class="Table">
                <div class="Row">
                    <div class="Cell">
                        ID :
                    </div>
                    <div class="Cell">
                        <input type="text" id="itemId" ng-model="itemId" />
                    </div>
                </div>
                <div class="Row">
                    <div class="Cell">
                        First Name :
                    </div>
                    <div class="Cell">
                        <input type="text" id="firstName" ng-model="firstName" />
                    </div>
                </div>
                <div class="Row">
                    <div class="Cell">
                        Last Name :
                    </div>
                    <div class="Cell">
                        <input type="text" id="lastName" ng-model="lastName" />
                    </div>
                </div>
                <div class="Row">
                    <div class="Cell">

                    </div>
                    <div class="Cell">
                        <input type="button" id="btnEditContact" value="Edit Contact" ng-click="editContact()" />
                    </div>
                </div>
            </div>
        </div>
        <hr />


        <h3>Delete Contacts</h3>
        <div ng-controller="delItemsController">
            <div class="Table">
                <div class="Row">
                    <div class="Cell">
                        ID :
                    </div>
                    <div class="Cell">
                        <input type="text" id="itemId" ng-model="itemId" />
                    </div>
                </div>              
                <div class="Row">
                    <div class="Cell">

                    </div>
                    <div class="Cell">
                        <input type="button" id="btnDelContact" value="Delete Contact" ng-click="delContact()" />
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

In the head section, I have made reference to the JQuery and the AngularJS libraries. And I have also referred the controller script [listItems.controller.js]. I have also added some styling script for the webpart.

Controller Code

Below is the controller code. The controller name is according to the operation it performs.


var spApp = angular
                .module("spApp", [])
                .controller("viewItemsController", function ($scope, $http) {
                    var url = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('Contacts')/items?$select=Title,FirstName,ID";
                    $http(
                    {
                        method: "GET",
                        url: url,
                        headers: { "accept": "application/json;odata=verbose" }
                    }
                    ).success(function (data, status, headers, config) {
                        $scope.contacts = data.d.results;
                    }).error(function (data, status, headers, config) {
                    });
                    
                })

                .controller("addItemsController", function ($scope, $http) {
                    var url = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('Contacts')/items";
                    var vm = $scope;
                    vm.addContact = function () {
                        return $http({
                            headers: { "Accept": "application/json; odata=verbose", "X-RequestDigest": jQuery("#__REQUESTDIGEST").val() },
                            method: "POST",
                            url: url,
                            data: {
                                'Title': vm.lastName,
                                'FirstName': vm.firstName
                            }
                        })
                        .then(saveContact)
                        .catch(function (message) {
                            console.log("addContact() error: " + message);
                        });
                        function saveContact(data, status, headers, config) {
                            alert("Item Added Successfully");
                            return data.data.d;
                        }
                    }
                })

                .controller("editItemsController", function ($scope, $http) {
                    
                    var vm = $scope;                    
                    vm.editContact = function () {
                        var data = {
                            '__metadata': {
                                'type': 'SP.Data.ContactsListItem'
                            },
                            'Title': vm.lastName,
                            'FirstName': vm.firstName
                        };
                        return $http({
                            headers: {
                                "Accept": "application/json; odata=verbose",
                                "Content-Type": "application/json; odata=verbose",
                                "X-HTTP-Method": "MERGE",
                                "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                                "Content-Length": data.length,
                                'IF-MATCH': "*"
                            },
                            method: "POST",
                            url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('Contacts')/items(" + vm.itemId + ")",
                            data: data
                        })
                        .then(saveContact)
                        .catch(function (message) {
                            console.log("editContact() error: " + message);
                        });
                        function saveContact(data, status, headers, config) {
                            alert("Item Edited Successfully");
                            return data.data.d;
                        }
                    }
                })

                .controller("delItemsController", function ($scope, $http) {
                    
                    var vm = $scope;                    

                    vm.delContact = function () {
                        return $http({
                            headers: {
                                "X-HTTP-Method": "DELETE",
                                "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                                'IF-MATCH': "*"
                            },
                            method: "POST",
                            url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('Contacts')/items(" + vm.itemId + ")"
                        })
                        .then(saveContact)
                        .catch(function (message) {
                            console.log("delContact() error: " + message);
                        });
                        function saveContact(data, status, headers, config) {
                            alert("Item Deleted Successfully");
                            return data.data.d;
                        }
                    }
                });

Hope this post is helpful for folks working purely on client side scripting with SharePoint in Office 365.

Comments

  1. Hi Sid, thanks for your blog. After reading your blog, I am able to read the data from List but unable to perform add operation. Need your help on it.

    ReplyDelete
  2. Hi,
    You have written very nice article. I acquired good knowledge about AngularJS. Keep it up! I will follow up your blog for feature post.
    Regards,
    best AngularJS2 online training in Hyderabad, India

    ReplyDelete
  3. I really appreciate information shared above. It’s of great help. If someone want to learn Online (Virtual) instructor lead live training in ANGULAR JS, kindly contact us http://www.maxmunus.com/contact
    MaxMunus Offer World Class Virtual Instructor led training on ANGULAR JS. We have industry expert trainer. We provide Training Material and Software Support. MaxMunus has successfully conducted 100000+ trainings in India, USA, UK, Australlia, Switzerland, Qatar, Saudi Arabia, Bangladesh, Bahrain and UAE etc.
    For Demo Contact us.
    Nitesh Kumar
    MaxMunus
    E-mail: nitesh@maxmunus.com
    Skype id: nitesh_maxmunus
    Ph:(+91) 8553912023
    http://www.maxmunus.com/




    ReplyDelete
  4. I had to add metadata to the data to get it Add Items

    data: {
    'Title': vm.LastName,
    'FirstName': vm.FirstName,
    "__metadata": { "type": "SP.Data.MyContactsListItem" }
    }

    ReplyDelete
    Replies
    1. I get a 403 Forbidden error during add operation. The app has Full Control over the list. Am I missing something?

      Delete
    2. This comment has been removed by the author.

      Delete
    3. i am experiencing the same issue

      Delete
  5. How do you make the data update after you add an item?

    ReplyDelete
    Replies
    1. $timeout in angular is similar to window.setTimeout.

      Delete
  6. Very nice post.really I apperciate your blog.Thanks for sharing.keep sharing more blogs.

    หนังไทยใหม่

    ReplyDelete
  7. Very Nice post thanks for sharing valuable information with us. see this once at Angularjs Online Training

    ReplyDelete
  8. Thanks for sharing information. Your web-site is very cool. I am impressed by the details that you have on this blog. It reveals how nicely you perceive this subject.. :)
    AngularJS Training in Chennai | AngularJS Training Institute in Chennai

    ReplyDelete
  9. very informative blog and useful article thank you for sharing with us , keep posting learn more Really nice blog post.provided a helpful information.I hope that you will post more updates like this AngularJS Online Training Bangalore

    ReplyDelete

  10. This is really an amazing article. Keep up the great work. Click here to know more about How to PlayBox HD movie download For ios

    movie app download ios

    Movie PlayBox

    PlayBox for Mac

    ReplyDelete

Post a Comment

Popular posts from this blog

The all new Movie Central

Movie Central 4.0 (New Release in works)

How to install nVidia Optimus driver