Provider Hosted MVC App With AngularJS in SharePoint - Part 2

Let's start with Provider Hosted MVC App with AngularJS - Part 2. In this part we are going to perform CRUD operation's with SharePoint APP Model and AngularJS.

Please Reference below link to understand how to create Provider Hosted MVC App With AngularJS.

SharePoint HostWeb List Structure

The following is a list structure which we are referencing for our application.

Employee catalog

We are going to create the following CRUD operation UI Design and final output format.

CRUD operation UI Design

Lets start with user data entry form design. when we are saying user entry form, it means we need to have validation applied to controls.

AngularJS validation logic reside in specific JavaScript file named angular-messages.js, so we need to add reference of that file in our project first.

add reference

When we think about validation, <form></form> control comes in existence. When end user enter valid data and submits data to the server, other stay on same page till the user fill correct form entries.

Let's check the following code & try to understand which property is used for which purpose in code.

Step 1: Add form tag with unique name so we can reference that name to check state of form- Valid/InValid.

  1. <form name="EmployeeForm" class="elegant-aero">   
Step 2: Steps to apply AngularJS validation attributes and showing the error message

Add html control with unique name. If the form field is required, then add " required " attribute to it.

Error Message: The ngModel directive expose an $error object. We can integrate $errro object with ngMessages to display control error message in easy way.

 

  • ng-message="required": It corresponds to attribute we added to HTML control.
    1. <input type="text" class="form-control" ng-model="Employee.EmpID" name="EmployeeID" required />      
    2.                       
    3. <div ng-messages="EmployeeForm.EmployeeID.$error">      
    4.        <div ng-message="required" class="ErrorSymbol">*</div>      
    5. </div>   
  • ng-message="pattern": It corresponds to error message if specified pattern is not matching with user input data.
    1. <input type="text" class="form-control" ng-model="Employee.EmpAge" name="EmployeeAge" ng-pattern="/^[0-9]+$/" required />    
    2.                            
    3.                       
    4. <div ng-messages="EmployeeForm.EmployeeAge.$error">    
    5.      <div ng-message="required" class="ErrorSymbol">*</div>    
    6.      <div ng-message="pattern" class="ErrorText">Must be a digit</div>    
    7. </div>    
    8.            

Save Button

In the starting save button is disabled. When user fills the form with valid data, save button gets activated.

  1. <button ng:click="save($event)" ng:disabled="isSaveDisabled()" class="btn btn-small btn-primary">Save </button>   
JS code

The following code indicates how to check form state and return value as true or false.
  1. $scope.isSaveDisabled = function () {    
  2.        
  3.     var Status = this.EmployeeForm.$invalid;               
  4.     return Status;    
When above method i.e " isSaveDisabled " returns true, control goes to save method with current employee details as input parameter.

Form control:
  1. <form name="EmployeeForm" class="elegant-aero">    
  2.    <table class="table table-condensed table-striped table-bordered">    
  3.        <tr>    
  4.            <td class="LblColumn">Employee Id:</td>    
  5.            <td class="DataColumn">    
  6.                <input type="text" class="form-control" ng-model="Employee.EmpID" name="EmployeeID" required />    
  7.            </td>    
  8.            <td class="ErrorColumn">    
  9.                <div ng-messages="EmployeeForm.EmployeeID.$error">    
  10.                    <div ng-message="required" class="ErrorSymbol">*</div>    
  11.                </div>    
  12.            </td>    
  13.        </tr>    
  14.        <tr>    
  15.            <td class="LblColumn">Employee Name:</td>    
  16.            <td class="DataColumn">    
  17.                <input type="text" class="form-control" ng-model="Employee.EmpName" name="EmployeeName" required />    
  18.            </td>    
  19.            <td class="ErrorColumn">    
  20.                <div ng-messages="EmployeeForm.EmployeeName.$error">    
  21.                    <div ng-message="required" class="ErrorSymbol">*</div>    
  22.                </div>    
  23.            </td>    
  24.        </tr>    
  25.        <tr>    
  26.            <td class="LblColumn">Employee Address:</td>    
  27.            <td class="DataColumn">    
  28.                <input type="text" class="form-control" ng-model="Employee.EmpAddress" name="EmployeeAddress" required />    
  29.            </td>    
  30.            <td class="ErrorColumn">    
  31.                <div ng-messages="EmployeeForm.EmployeeAddress.$error">    
  32.                    <div ng-message="required" class="ErrorSymbol">*</div>    
  33.                </div>    
  34.            </td>    
  35.        </tr>    
  36.        <tr>    
  37.            <td class="LblColumn">Employee Age:</td>    
  38.            <td class="DataColumn">    
  39.                <input type="text" class="form-control" ng-model="Employee.EmpAge" name="EmployeeAge" ng-pattern="/^[0-9]+$/" required />    
  40.            </td>    
  41.            <td class="ErrorColumn">    
  42.                <div ng-messages="EmployeeForm.EmployeeAge.$error">    
  43.                    <div ng-message="required" class="ErrorSymbol">*</div>    
  44.                    <div ng-message="pattern" class="ErrorText">Must be a digit</div>    
  45.                </div>    
  46.            </td>    
  47.        </tr>    
  48.        <tr>    
  49.            <td class="LblColumn">Employee Qualification:</td>    
  50.            <td class="DataColumn">    
  51.                <input type="text" class="form-control" ng-model="Employee.EmpQualification" name="EmployeeQualification" required />    
  52.            </td>    
  53.            <td class="ErrorColumn">    
  54.                <div ng-messages="EmployeeForm.EmployeeQualification.$error">    
  55.                    <div ng-message="required" class="ErrorSymbol">*</div>    
  56.                </div>    
  57.            </td>    
  58.        </tr>    
  59.        <tr>    
  60.            <td class="LblColumn">Employee Designation:</td>    
  61.            <td class="DataColumn">    
  62.                <input type="text" class="form-control" ng-model="Employee.EmpDesignation" name="EmployeeDesignation" required />    
  63.            </td>    
  64.            <td class="ErrorColumn">    
  65.                <div ng-messages="EmployeeForm.EmployeeDesignation.$error">    
  66.                    <div ng-message="required" class="ErrorSymbol">*</div>    
  67.                </div>    
  68.            </td>    
  69.        </tr>    
  70.        <tr>    
  71.            <td colspan="2">    
  72.                @*<input type="button" id="btnaddcategory" value="Save" ng-click="save($event)" class="btn btn-small btn-primary" />*@    
  73.                <button ng:click="save($event)" ng:disabled="isSaveDisabled()" class="btn btn-small btn-primary">Save </button>    
  74.            </td>    
  75.            <td>    
  76.                <input type="text" class="form-control" ng-model="Employee.ID" style="visibility:hidden">    
  77.            </td>    
  78.        </tr>    
  79.    </table>    
  80. lt;/form>   
Table Control

We want to perform CRUD operation so need to add update & delete button. Therefore, I added that button to table via AngularJS.

Article Part-1 <table></table> control and this table control you notice some difference here.
Inside <tbody></tbody> control I added a row with two column , first for Update button & second for Delete button.

 

  • Update button: ng-click="loadRecord(gridItem, $event)".

  • Delete button: ng-click="DeleteItem(gridItem.ID, $event)".
    1. <table tr-ng-grid="" items="EmployeeMaster" locale="en">    
    2.             <thead>    
    3.                 <tr>    
    4.                     <th field-name="EmpID" display-name="Employee ID"></th>    
    5.                     <th field-name="EmpName" display-name="Employee Name"></th>    
    6.                     <th field-name="EmpAddress" display-name="Address"></th>    
    7.                     <th field-name="EmpAge" display-name="Age"></th>    
    8.                     <th field-name="EmpQualification" display-name="Qualification"></th>    
    9.                     <th field-name="EmpDesignation" display-name="Designation"></th>    
    10.                 </tr>    
    11.             </thead>    
    12.             <tbody>    
    13.                 <tr>    
    14.                     <td>    
    15.                         <input type="button" id="btnUpdatEmployee" class="btn btn-success"    
    16.                                value="Update"    
    17.                                ng-click="loadRecord(gridItem, $event)" />    
    18.                     </td>    
    19.                     <td>    
    20.                         <input type="button" id="btnDeleteEmployee" class="btn btn-success"    
    21.                                value="Delete"    
    22.                                onclick="javascript: confirm('Do you want to delete record ??');"    
    23.                                ng-click="DeleteItem(gridItem.ID, $event)" />    
    24.                     </td>    
    25.                 </tr>    
    26.             </tbody>    
    27. </table>  

Index.cshtml Source Code

Please check below the following source code changes like new script reference, <table> control change,<form> control integration in order to design above UI.

  1. @{    
  2.     ViewBag.Title = "Home Page";    
  3. }    
  4.     
  5. <!-- Javascript from hives Layout folder -->    
  6. <script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>    
  7. <script type="text/javascript" src="/_layouts/15/sp.js"></script>    
  8. <script type="text/ecmascript" src="/_layouts/SP.Core.js"></script>    
  9. <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js"></script>    
  10.     
  11. <!-- Basic JS Files -->    
  12. <script src="~/AngularJSScript/BasicJS/angular.min.js"></script>    
  13. <script src="~/AngularJSScript/BasicJS/trNgGrid.js"></script>    
  14. <script src="~/AngularJSScript/BasicJS/angular-messages.js"></script>    
  15.     
  16. <!-- Custom JS Files -->    
  17. <script src="~/AngularJSScript/CustomJS/app-constants.js"></script>    
  18. <script src="~/AngularJSScript/CustomJS/app-main.js"></script>    
  19. <script src="~/AngularJSScript/CustomJS/app-data-service.js"></script>    
  20. <script src="~/AngularJSScript/CustomJS/app-home-controller.js"></script>    
  21.     
  22. <link href="~/Content/bootstrap.min.css" rel="stylesheet" />    
  23. <link href="~/Content/trNgGrid.min.css" rel="stylesheet" />    
  24.     
  25. <style>    
  26.     .LblColumn {    
  27.         width: 15%;    
  28.     }    
  29.     
  30.     .DataColumn {    
  31.         width: 25%;    
  32.     }    
  33.     
  34.     .ErrorSymbol {    
  35.         color: red;    
  36.         font-size: 30px;    
  37.     }    
  38.     
  39.     .ErrorText {    
  40.         color: red;    
  41.     }    
  42.     
  43.     .ErrorColumn{    
  44.         width:5%;    
  45.     }    
  46. </style>    
  47. <div ng-app="AngularApp">    
  48.     <div ng-controller="HomeController">    
  49.     
  50.         <div>    
  51.             <h3>Provider Hosted Mvc App with AngularJS</h3>    
  52.         </div><br />    
  53.         <div style="width:60%">    
  54.             <form name="EmployeeForm" class="elegant-aero">    
  55.                 <table class="table table-condensed table-striped table-bordered">    
  56.                     <tr>    
  57.                         <td class="LblColumn">Employee Id:</td>    
  58.                         <td class="DataColumn">    
  59.                             <input type="text" class="form-control" ng-model="Employee.EmpID" name="EmployeeID" required />    
  60.                         </td>    
  61.                         <td class="ErrorColumn">    
  62.                             <div ng-messages="EmployeeForm.EmployeeID.$error">    
  63.                                 <div ng-message="required" class="ErrorSymbol">*</div>    
  64.                             </div>    
  65.                         </td>    
  66.                     </tr>    
  67.                     <tr>    
  68.                         <td class="LblColumn">Employee Name:</td>    
  69.                         <td class="DataColumn">    
  70.                             <input type="text" class="form-control" ng-model="Employee.EmpName" name="EmployeeName" required />    
  71.                         </td>    
  72.                         <td class="ErrorColumn">    
  73.                             <div ng-messages="EmployeeForm.EmployeeName.$error">    
  74.                                 <div ng-message="required" class="ErrorSymbol">*</div>    
  75.                             </div>    
  76.                         </td>    
  77.                     </tr>    
  78.                     <tr>    
  79.                         <td class="LblColumn">Employee Address:</td>    
  80.                         <td class="DataColumn">    
  81.                             <input type="text" class="form-control" ng-model="Employee.EmpAddress" name="EmployeeAddress" required />    
  82.                         </td>    
  83.                         <td class="ErrorColumn">    
  84.                             <div ng-messages="EmployeeForm.EmployeeAddress.$error">    
  85.                                 <div ng-message="required" class="ErrorSymbol">*</div>    
  86.                             </div>    
  87.                         </td>    
  88.                     </tr>    
  89.                     <tr>    
  90.                         <td class="LblColumn">Employee Age:</td>    
  91.                         <td class="DataColumn">    
  92.                             <input type="text" class="form-control" ng-model="Employee.EmpAge" name="EmployeeAge" ng-pattern="/^[0-9]+$/" required />    
  93.                         </td>    
  94.                         <td class="ErrorColumn">    
  95.                             <div ng-messages="EmployeeForm.EmployeeAge.$error">    
  96.                                 <div ng-message="required" class="ErrorSymbol">*</div>    
  97.                                 <div ng-message="pattern" class="ErrorText">Must be a digit</div>    
  98.                             </div>    
  99.                         </td>    
  100.                     </tr>    
  101.                     <tr>    
  102.                         <td class="LblColumn">Employee Qualification:</td>    
  103.                         <td class="DataColumn">    
  104.                             <input type="text" class="form-control" ng-model="Employee.EmpQualification" name="EmployeeQualification" required />    
  105.                         </td>    
  106.                         <td class="ErrorColumn">    
  107.                             <div ng-messages="EmployeeForm.EmployeeQualification.$error">    
  108.                                 <div ng-message="required" class="ErrorSymbol">*</div>    
  109.                             </div>    
  110.                         </td>    
  111.                     </tr>    
  112.                     <tr>    
  113.                         <td class="LblColumn">Employee Designation:</td>    
  114.                         <td class="DataColumn">    
  115.                             <input type="text" class="form-control" ng-model="Employee.EmpDesignation" name="EmployeeDesignation" required />    
  116.                         </td>    
  117.                         <td class="ErrorColumn">    
  118.                             <div ng-messages="EmployeeForm.EmployeeDesignation.$error">    
  119.                                 <div ng-message="required" class="ErrorSymbol">*</div>    
  120.                             </div>    
  121.                         </td>    
  122.                     </tr>    
  123.                     <tr>    
  124.                         <td colspan="2">    
  125.                             @*<input type="button" id="btnaddcategory" value="Save" ng-click="save($event)" class="btn btn-small btn-primary" />*@    
  126.                             <button ng:click="save($event)" ng:disabled="isSaveDisabled()" class="btn btn-small btn-primary">Save </button>    
  127.                         </td>    
  128.                         <td>    
  129.                             <input type="text" class="form-control" ng-model="Employee.ID" style="visibility:hidden">    
  130.                         </td>    
  131.                     </tr>    
  132.                 </table>    
  133.             </form>    
  134.         </div><br />    
  135.         <div style="color:green">    
  136.             <h4>trNgGrid control - To show List Data</h4>    
  137.         </div><br />    
  138.         <table tr-ng-grid="" items="EmployeeMaster" locale="en">    
  139.             <thead>    
  140.                 <tr>    
  141.                     <th field-name="EmpID" display-name="Employee ID"></th>    
  142.                     <th field-name="EmpName" display-name="Employee Name"></th>    
  143.                     <th field-name="EmpAddress" display-name="Address"></th>    
  144.                     <th field-name="EmpAge" display-name="Age"></th>    
  145.                     <th field-name="EmpQualification" display-name="Qualification"></th>    
  146.                     <th field-name="EmpDesignation" display-name="Designation"></th>    
  147.                 </tr>    
  148.             </thead>    
  149.             <tbody>    
  150.                 <tr>    
  151.                     <td>    
  152.                         <input type="button" id="btnUpdatEmployee" class="btn btn-success"    
  153.                                value="Update"    
  154.                                ng-click="loadRecord(gridItem, $event)" />    
  155.                     </td>    
  156.                     <td>    
  157.                         <input type="button" id="btnDeleteEmployee" class="btn btn-success"    
  158.                                value="Delete"    
  159.                                onclick="javascript: confirm('Do you want to delete record ??');"    
  160.                                ng-click="DeleteItem(gridItem.ID, $event)" />    
  161.                     </td>    
  162.                 </tr>    
  163.             </tbody>    
  164.         </table>    
  165.     </div>    
  166. </div>   
CRUD Operation JavaScript Code

In Part -1 , Read function has completed i.e Load() method. some new method need to added here.

Note - We loaded all out of box JS file in Load() function at start so no need to load same file again and again, otherwise it gives you error or nothing happens.

app-main.js:

We first need to modify Dependent module names, since we want to apply validation to html control, 'ngMessages' need to be added as dependent module.
  1. (function () {    
  2.     
  3.     console.log('app-main.js loaded ..');    
  4.        
  5.     angular.module(window.AngularApp_constants.architecture.modules.MainApp.moduleKey, ['trNgGrid''ngMessages']);    
  6.     
  7. })();  
app-home-controller.js:

I will explain all function of "app-home-controller.js" file first and then we move to DataLayer functions.

For better programming purpose, we are going to integrate Save() and Update() functionality in a single function based on flag value. IsUpdate flag set to false at start, when needed this flag value get changed.
  1. $scope.IsUpdate = false;   
When Save button is clicked, as per flag value, either of the function get called.
  1. $scope.IsUpdate = false;    
  2.     
  3. $scope.Employee = {    
  4.     ID: '',    
  5.     EmpID: '',    
  6.     EmpName: "",    
  7.     EmpAddress: "",    
  8.     EmpAge: "",    
  9.     EmpQualification: "",    
  10.     EmpDesignation : ""    
  11. };    
  12.     
  13. $scope.save = function ($event) {    
  14.     
  15.     $event.preventDefault();    
  16.     
  17.     if (!$scope.IsUpdate) {    
  18.         //alert('Save');    
  19.         var promiseSave = AngularDataService.save($scope.Employee);    
  20.         window.location.reload();    
  21.     }    
  22.     else {    
  23.        //alert('Update');    
  24.         var promiseUpdate = AngularDataService.update($scope.Employee);    
  25.         window.location.reload();                  
  26.     }    
  27. }   
When Update button is clicked, loadRecord() function get called.
  1. /********* Update Employee ***********/    
  2.     
  3. $scope.loadRecord = function (Emp, $event) {    
  4.     $event.preventDefault();    
  5.         
  6.     $scope.Employee.ID = Emp.ID;    
  7.     $scope.Employee.EmpID = Emp.EmpID;    
  8.     $scope.Employee.EmpName = Emp.EmpName;    
  9.     $scope.Employee.EmpAddress = Emp.EmpAddress;    
  10.     $scope.Employee.EmpAge = Emp.EmpAge;    
  11.     $scope.Employee.EmpQualification = Emp.EmpQualification;    
  12.     $scope.Employee.EmpDesignation = Emp.EmpDesignation;    
  13.     
  14.     $scope.IsUpdate = true;    
  15. }   
When Delete button is clicked, DeleteItem() function get called.
  1. /********* Delete Employee ***********/    
  2.   
  3. $scope.DeleteItem = function (ItemID, $event) {    
  4.     //alert("Delete Called.");    
  5.     var promiseDelete = AngularDataService.delete(ItemID);    
  6. }   
app-home-controller.js source code
  1. (function () {    
  2.     
  3.     console.log('app-home-controller.js loaded ..');    
  4.     'use strict'    
  5.     
  6.     angular    
  7.           .module(window.AngularApp_constants.architecture.modules.MainApp.moduleKey)    
  8.           .controller('HomeController', HomeController)    
  9.     
  10.     HomeController.$inject = ['$scope''$location''app-data-service'];    
  11.     
  12.     function HomeController($scope, $location, AngularDataService) {    
  13.     
  14.        /********* Fill EmployeeMaster *********/    
  15.         $scope.EmployeeMaster = [];    
  16.     
  17.         Load();    
  18.     
  19.         function Load() {    
  20.     
  21.             console.log("Load called");    
  22.     
  23.             var promiseGet = AngularDataService.get();    
  24.             promiseGet.then(function (resp) {    
  25.                 $scope.EmployeeMaster = resp;                  
  26.             }, function (err) {    
  27.                 $scope.Message = "Error " + err.status;    
  28.             });    
  29.         }    
  30.     
  31.         /****** Save Employee Record *******/    
  32.     
  33.         $scope.IsUpdate = false;    
  34.            
  35.         $scope.Employee = {    
  36.             ID: '',    
  37.             EmpID: '',    
  38.             EmpName: "",    
  39.             EmpAddress: "",    
  40.             EmpAge: "",    
  41.             EmpQualification: "",    
  42.             EmpDesignation : ""    
  43.         };    
  44.     
  45.         $scope.save = function ($event) {    
  46.     
  47.             $event.preventDefault();    
  48.     
  49.             if (!$scope.IsUpdate) {    
  50.                 //alert('Save');    
  51.                 var promiseSave = AngularDataService.save($scope.Employee);    
  52.                 window.location.reload();    
  53.             }    
  54.             else {    
  55.                //alert('Update');    
  56.                 var promiseUpdate = AngularDataService.update($scope.Employee);    
  57.                 window.location.reload();                  
  58.             }    
  59.         }    
  60.     
  61.         /********* Update Employee ***********/    
  62.     
  63.         $scope.loadRecord = function (Emp, $event) {    
  64.             $event.preventDefault();    
  65.                 
  66.             $scope.Employee.ID = Emp.ID;    
  67.             $scope.Employee.EmpID = Emp.EmpID;    
  68.             $scope.Employee.EmpName = Emp.EmpName;    
  69.             $scope.Employee.EmpAddress = Emp.EmpAddress;    
  70.             $scope.Employee.EmpAge = Emp.EmpAge;    
  71.             $scope.Employee.EmpQualification = Emp.EmpQualification;    
  72.             $scope.Employee.EmpDesignation = Emp.EmpDesignation;    
  73.     
  74.             $scope.IsUpdate = true;    
  75.         }    
  76.     
  77.         /********* Delete Employee ***********/    
  78.     
  79.         $scope.DeleteItem = function (ItemID, $event) {    
  80.             //alert("Delete Called.");    
  81.             var promiseDelete = AngularDataService.delete(ItemID);    
  82.         }    
  83.     
  84.         /***********************************/    
  85.     
  86.         $scope.isSaveDisabled = function () {    
  87.                
  88.             var Status = this.EmployeeForm.$invalid;               
  89.             return Status;    
  90.         }    
  91.     }    
  92.     
  93. })();  
app-data-service.js

When we want to save employee record, we need to call save() function of DataLayer.
  1. /*********** Create **************/    
  2. his.save = function (Employee) {    
  3.   
  4.    var deferred = $q.defer();    
  5.   
  6.    try {    
  7.   
  8.        var ctx = new SP.ClientContext(appweburl);    
  9.   
  10.        //Access host web from app using JavaScript CSOM    
  11.        var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);    
  12.        ctx.set_webRequestExecutorFactory(factory);    
  13.   
  14.        var appCtxSite = new SP.AppContextSite(ctx, hostweburl);    
  15.        var web = appCtxSite.get_web();    
  16.   
  17.        var list = web.get_lists().getByTitle(listTitle);    
  18.        var listCreationInformation = new SP.ListItemCreationInformation();    
  19.   
  20.        ctx.load(list);    
  21.        var listItem = list.addItem(listCreationInformation);    
  22.   
  23.        listItem.set_item("EmpID", Employee.EmpID);    
  24.        listItem.set_item("EmpName", Employee.EmpName);    
  25.        listItem.set_item("EmpAddress", Employee.EmpAddress);    
  26.        listItem.set_item("EmpAge", Employee.EmpAge);    
  27.        listItem.set_item("EmpQualification", Employee.EmpQualification);    
  28.        listItem.set_item("EmpDesignation", Employee.EmpDesignation);    
  29.   
  30.        listItem.update();    
  31.        ctx.load(listItem);    
  32.   
  33.        //Execute the batch Asynchronously    
  34.        ctx.executeQueryAsync(    
  35.                Function.createDelegate(this, function () {    
  36.                    console.log('Item Created');    
  37.                }),    
  38.                Function.createDelegate(this, function (sender, args) {    
  39.                  console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  40.                    deferred.reject('Request failed. ' + args.get_message()+'\n' + args.get_stackTrace());  
  41.                })    
  42.        );    
  43.    }    
  44.    catch (Error) {    
  45.        console.log("Error : " + Error);    
  46.    }    
  47.   
  48.    return deferred.promise;    
  49. ;  
When we want to update employee record, we need to call update() function of DataLayer.
  1. /*********** Update **************/    
  2. this.update = function (Employee) {    
  3.     
  4.     var deferred = $q.defer();    
  5.     
  6.     try {    
  7.     
  8.         var ctx = new SP.ClientContext(appweburl);    
  9.     
  10.         //Access host web from app using JavaScript CSOM    
  11.         var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);    
  12.         ctx.set_webRequestExecutorFactory(factory);    
  13.     
  14.         var appCtxSite = new SP.AppContextSite(ctx, hostweburl);    
  15.         var web = appCtxSite.get_web();    
  16.     
  17.         var list = web.get_lists().getByTitle(listTitle);    
  18.     
  19.         var listItem = list.getItemById(Employee.ID);    
  20.         ctx.load(listItem);    
  21.     
  22.         listItem.set_item("EmpID", Employee.EmpID);    
  23.         listItem.set_item("EmpName", Employee.EmpName);    
  24.         listItem.set_item("EmpAddress", Employee.EmpAddress);    
  25.         listItem.set_item("EmpAge", Employee.EmpAge);    
  26.         listItem.set_item("EmpQualification", Employee.EmpQualification);    
  27.         listItem.set_item("EmpDesignation", Employee.EmpDesignation);    
  28.     
  29.         listItem.update();    
  30.     
  31.         //Execute the batch Asynchronously    
  32.         ctx.executeQueryAsync(    
  33.                 Function.createDelegate(this, function () {    
  34.                     console.log('Item Updated');    
  35.                 }),    
  36.                 Function.createDelegate(this, function (sender, args) {    
  37.                     console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  38.                     deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  39.                 })    
  40.         );    
  41.     }    
  42.     catch (Error) {    
  43.         console.log("Error : " + Error);    
  44.     }    
  45.     return deferred.promise;    
  46. }   
When we want to update employee record, we need to call delete() function of DataLayer.
  1. /*********** Delete **************/    
  2. this.delete = function (EmpID) {    
  3.     
  4.     var deferred = $q.defer();    
  5.     
  6.     var ctx = new SP.ClientContext(appweburl);    
  7.     
  8.     //Access host web from app using JavaScript CSOM    
  9.     var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);    
  10.     ctx.set_webRequestExecutorFactory(factory);    
  11.     
  12.     var appCtxSite = new SP.AppContextSite(ctx, hostweburl);    
  13.     var web = appCtxSite.get_web();    
  14.     
  15.     var list = web.get_lists().getByTitle(listTitle);    
  16.     
  17.     var itemId = EmpID;    
  18.     listItem = list.getItemById(itemId);    
  19.     listItem.deleteObject();    
  20.     
  21.     ctx.executeQueryAsync(    
  22.         Function.createDelegate(this, function () {    
  23.             console.log('Item deleted: ' + itemId);    
  24.         }),    
  25.         Function.createDelegate(this, function (sender, args) {    
  26.             console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  27.             deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  28.         })    
  29.     );    
  30.     
  31.     return deferred.promise;    
  32. }    
  33. /***********************/    
app-data-service.js source code
  1. (function () {    
  2.     
  3.     console.log('app-data-service.js loaded...');    
  4.     'use strict'    
  5.     
  6.     angular    
  7.             .module(window.AngularApp_constants.architecture.modules.MainApp.moduleKey)    
  8.             .service('app-data-service', AngularDataService);    
  9.     
  10.     AngularDataService.$inject = ['$q''$http''$timeout'];    
  11.     
  12.     function AngularDataService($q, $http, $timeout) {    
  13.     
  14.         function QueryStringParameter(paramToRetrieve) {    
  15.             var params =    
  16.             document.URL.split("?")[1].split("&");    
  17.             var strParams = "";    
  18.             for (var i = 0; i < params.length; i = i + 1) {    
  19.                 var singleParam = params[i].split("=");    
  20.                 if (singleParam[0] == paramToRetrieve) {    
  21.                     return singleParam[1];    
  22.                 }    
  23.             }    
  24.         }    
  25.     
  26.         var hostweburl;    
  27.         var appweburl;    
  28.     
  29.         //The SharePoint App where the App is actualy installed    
  30.         hostweburl = decodeURIComponent(QueryStringParameter('SPHostUrl'));    
  31.     
  32.         //The App web where the component to be accessed by the app are deployed    
  33.         appweburl = decodeURIComponent(QueryStringParameter('SPAppWebUrl'));    
  34.     
  35.         // resources are in URLs in the form: web_url/_layouts/15/resource    
  36.         var scriptbase = hostweburl + "/_layouts/15/";    
  37.         var listTitle = "EmployeeCatalog";    
  38.     
  39.         /*********** Read ***************/    
  40.     
  41.         this.get = function () {    
  42.     
  43.             var EmployeeArray = [];    
  44.     
  45.             var deferred = $q.defer();    
  46.     
  47.             // Load 15hives js files and continue to the successHandler    
  48.             $.getScript(scriptbase + "SP.Runtime.js",    
  49.                 function () {    
  50.                     $.getScript(scriptbase + "SP.js",    
  51.                         function () {    
  52.                             $.getScript(scriptbase + "SP.RequestExecutor.js",    
  53.                                  function () {    
  54.     
  55.                                      //Represents the context for objects and operations.    
  56.                                      var context = new SP.ClientContext(appweburl);    
  57.     
  58.                                      //Access host web from app using JavaScript CSOM    
  59.                                      var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);    
  60.                                      context.set_webRequestExecutorFactory(factory);    
  61.     
  62.                                      var appContextSite = new SP.AppContextSite(context, hostweburl);    
  63.                                      var web = appContextSite.get_web();    
  64.                                      context.load(web);    
  65.     
  66.                                      //Access HostWeb List    
  67.                                      var list = web.get_lists().getByTitle(listTitle);    
  68.     
  69.                                      var camlQuery = SP.CamlQuery.createAllItemsQuery();    
  70.                                      this.listItems = list.getItems(camlQuery);    
  71.                                      context.load(this.listItems);    
  72.     
  73.                                      context.executeQueryAsync(    
  74.                                          Function.createDelegate(this, function () {    
  75.     
  76.                                              var ListEnumerator = this.listItems.getEnumerator();    
  77.     
  78.                                              while (ListEnumerator.moveNext()) {    
  79.     
  80.                                                  var currentItem = ListEnumerator.get_current();    
  81.                                                  EmployeeArray.push({    
  82.                                                      ID: currentItem.get_item('ID'),    
  83.                                                      EmpID: currentItem.get_item('EmpID'),    
  84.                                                      EmpName: currentItem.get_item('EmpName'),    
  85.                                                      EmpAddress: currentItem.get_item('EmpAddress'),    
  86.                                                      EmpAge: currentItem.get_item('EmpAge'),    
  87.                                                      EmpQualification: currentItem.get_item('EmpQualification'),    
  88.                                                      EmpDesignation: currentItem.get_item('EmpDesignation')    
  89.                                                  });    
  90.                                              }    
  91.     
  92.                                              console.log(EmployeeArray);    
  93.                                              deferred.resolve(EmployeeArray);    
  94.                                          }),    
  95.                                          Function.createDelegate(this, function (sender, args) {    
  96.                                              deferred.reject('Request failed. ' + args.get_message());    
  97.                                              console.log("Error : " + args.get_stackTrace());    
  98.                                          })    
  99.                                      );    
  100.                                  });    
  101.                         });    
  102.                 });    
  103.     
  104.             return deferred.promise;    
  105.         }; // Get    
  106.     
  107.     
  108.         /*********** Create **************/    
  109.         this.save = function (Employee) {    
  110.     
  111.             var deferred = $q.defer();    
  112.     
  113.             try {    
  114.     
  115.                 var ctx = new SP.ClientContext(appweburl);    
  116.     
  117.                 //Access host web from app using JavaScript CSOM    
  118.                 var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);    
  119.                 ctx.set_webRequestExecutorFactory(factory);    
  120.     
  121.                 var appCtxSite = new SP.AppContextSite(ctx, hostweburl);    
  122.                 var web = appCtxSite.get_web();    
  123.     
  124.                 var list = web.get_lists().getByTitle(listTitle);    
  125.                 var listCreationInformation = new SP.ListItemCreationInformation();    
  126.     
  127.                 ctx.load(list);    
  128.                 var listItem = list.addItem(listCreationInformation);    
  129.     
  130.                 listItem.set_item("EmpID", Employee.EmpID);    
  131.                 listItem.set_item("EmpName", Employee.EmpName);    
  132.                 listItem.set_item("EmpAddress", Employee.EmpAddress);    
  133.                 listItem.set_item("EmpAge", Employee.EmpAge);    
  134.                 listItem.set_item("EmpQualification", Employee.EmpQualification);    
  135.                 listItem.set_item("EmpDesignation", Employee.EmpDesignation);    
  136.     
  137.                 listItem.update();    
  138.                 ctx.load(listItem);    
  139.     
  140.                 //Execute the batch Asynchronously    
  141.                 ctx.executeQueryAsync(    
  142.                         Function.createDelegate(this, function () {    
  143.                             console.log('Item Created');    
  144.                         }),    
  145.                         Function.createDelegate(this, function (sender, args) {    
  146.                             console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  147.                             deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  148.                         })    
  149.                 );    
  150.             }    
  151.             catch (Error) {    
  152.                 console.log("Error : " + Error);    
  153.             }    
  154.     
  155.             return deferred.promise;    
  156.         };    
  157.     
  158.         /*********** Update **************/    
  159.         this.update = function (Employee) {    
  160.     
  161.             var deferred = $q.defer();    
  162.     
  163.             try {    
  164.     
  165.                 var ctx = new SP.ClientContext(appweburl);    
  166.     
  167.                 //Access host web from app using JavaScript CSOM    
  168.                 var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);    
  169.                 ctx.set_webRequestExecutorFactory(factory);    
  170.     
  171.                 var appCtxSite = new SP.AppContextSite(ctx, hostweburl);    
  172.                 var web = appCtxSite.get_web();    
  173.     
  174.                 var list = web.get_lists().getByTitle(listTitle);    
  175.     
  176.                 var listItem = list.getItemById(Employee.ID);    
  177.                 ctx.load(listItem);    
  178.     
  179.                 listItem.set_item("EmpID", Employee.EmpID);    
  180.                 listItem.set_item("EmpName", Employee.EmpName);    
  181.                 listItem.set_item("EmpAddress", Employee.EmpAddress);    
  182.                 listItem.set_item("EmpAge", Employee.EmpAge);    
  183.                 listItem.set_item("EmpQualification", Employee.EmpQualification);    
  184.                 listItem.set_item("EmpDesignation", Employee.EmpDesignation);    
  185.     
  186.                 listItem.update();    
  187.     
  188.                 //Execute the batch Asynchronously    
  189.                 ctx.executeQueryAsync(    
  190.                         Function.createDelegate(this, function () {    
  191.                             console.log('Item Updated');    
  192.                         }),    
  193.                         Function.createDelegate(this, function (sender, args) {    
  194.                             console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  195.                             deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  196.                         })    
  197.                 );    
  198.             }    
  199.             catch (Error) {    
  200.                 console.log("Error : " + Error);    
  201.             }    
  202.             return deferred.promise;    
  203.         }    
  204.     
  205.         /*********** Delete **************/    
  206.         this.delete = function (EmpID) {    
  207.     
  208.             var deferred = $q.defer();    
  209.     
  210.             var ctx = new SP.ClientContext(appweburl);    
  211.     
  212.             //Access host web from app using JavaScript CSOM    
  213.             var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);    
  214.             ctx.set_webRequestExecutorFactory(factory);    
  215.     
  216.             var appCtxSite = new SP.AppContextSite(ctx, hostweburl);    
  217.             var web = appCtxSite.get_web();    
  218.     
  219.             var list = web.get_lists().getByTitle(listTitle);    
  220.     
  221.             var itemId = EmpID;    
  222.             listItem = list.getItemById(itemId);    
  223.             listItem.deleteObject();    
  224.     
  225.             ctx.executeQueryAsync(    
  226.                 Function.createDelegate(this, function () {    
  227.                     console.log('Item deleted: ' + itemId);    
  228.                 }),    
  229.                 Function.createDelegate(this, function (sender, args) {    
  230.                     console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  231.                     deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());    
  232.                 })    
  233.             );    
  234.     
  235.             return deferred.promise;    
  236.         }    
  237.         /***********************/    
  238.     
  239.     } // AngularDataService    
  240.     
  241. })();   
I hope you all liked this article as you liked the  Part-1 of this series.