Remove Attachments on SharePoint List Item using Angular

Ahamed Fazil Buhari
 
Senior Developer
December 4, 2017
 
Rate this article
 
Views
3805

Hello everyone,

In this article we will see how to delete attachments in SharePoint List Item using Angular. In my previous article we have seen, Get All Attachments From SharePoint List Item Using AngularJS and How To Handle Multiple File Selection And Validation On Input File Type Using AngularJS. Once we get all the files in the variable scope.attachedFile. We cannot upload attachment when we are updating some field in the item. To achieve this, we need to update item in separate and upload or remove file in separate. We can make use of promise $q in angular to upload file in list item once the item has been successfully created or updated.

Here I’ve created separate service for updating list item and uploading attachment in SharePoint list item. The service name is List_Context and Utilities service to get supporting components for CRUD header,

Utilities.js

 (function () {
     'use strict';
     var serviceId = 'Utilities';
 
     var Utilities = function () {
 
         var service = this;
         service.spHostUrl = _spPageContextInfo.siteAbsoluteUrl + _spPageContextInfo.webServerRelativeUrl;
 
         return {
             getRequestHeader: getRequestHeader,
             updateRequestHeader: updateRequestHeader,
             deleteRequestHeader: deleteRequestHeader
         };
 
         function getRequestHeader() {
             var getHeader = {
                 'headers': {
                     'accept': 'application/json;odata=verbose'
                 }
             };
             return getHeader;
         }
 
         function updateRequestHeader() {
             var updateHeader = {
                 'headers': {
                     "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                     'content-type': 'application/json;odata=verbose',
                     'accept': 'application/json;odata=verbose',
                     "IF-MATCH": "*",
                     "X-HTTP-Method": "MERGE"
                 }
             };
             return updateHeader;
         }
 
         function deleteRequestHeader() {
             var deleteHeader = {
                 'headers': {
                     "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                     'content-type': 'application/json;odata=verbose',
                     "IF-MATCH": "*"
                 }
             };
             return deleteHeader;
         }
     }
     var module = angular.module("Mainapp");
     module.factory(serviceId, Utilities);
 }());
 

List_Context.js

 (function () {
     'use strict';
     var serviceId = 'List_Context';
 
     var List_Context = function ($http, $q, Utilities) {
 
         return {
             getListData: getListData,
             updateListData: updateListData,
             checkFileExistsAndRemove: checkFileExistsAndRemove,
             uploadFileSP: uploadFileSP,
             getFileBuffer: getFileBuffer,
             deleteFile: deleteFile
         };
 
         function getListData(urlValue) {
             var deferred = $q.defer();
             $http.get(urlValue, Utilities.getRequestHeader())
                         .then(function (response) {
                             deferred.resolve(response.data.d);
                         }, function (error) {
                             deferred.reject(error);
                         });
             return deferred.promise;
         };
 
         function updateListData(listId, itemId, itemData, listName) {
             var deferred = $q.defer();
             var updateURL = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetById('" + listId + "')/Items" + '(' + itemId + ')';
             var entityFullName = getEntityTypeFullName(listName);
             var item = $.extend({
                 '__metadata': {
                     'type': entityFullName
                 }
             }, itemData);
             var jsonData = JSON.stringify(item);
 
             $http.post(updateURL, jsonData, Utilities.updateRequestHeader())
                         .then(function (response) {
                             deferred.resolve(response.data.d);
                         }, function (error) {
                             deferred.reject(error);
                         });
             return deferred.promise;
         };
 
         function checkFileExistsAndRemove(fileURL) {
             var deferred = $q.defer();
             var fullFileURL = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getFileByServerRelativeUrl('" + fileURL + "')";
             $http.get(fullFileURL, Utilities.getRequestHeader())
                         .then(function (response) {
                             deleteFile(fullFileURL)
                             .then(function (response) {
                                 deferred.resolve(response);
                             });
                         }, function (error) {
                             console.log('File does not exist');
                             deferred.reject(error);
                         });
             return deferred.promise;
         }
 
         function uploadFileSP(listName, itemID, bufferVal, fileName) {
             var urlValue = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('" + listName + "')/items(" + itemID + ")/AttachmentFiles/add(FileName='" + fileName + "')";
 
             $.ajax({
                 url: urlValue,
                 type: "POST",
                 data: bufferVal,
                 async: false,
                 processData: false,
                 headers: {
                     "accept": "application/json;odata=verbose",
                     "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                     "Content-Type": undefined
                 },
                 success: fileSuccess,
                 error: fileError
             });
             function fileSuccess(data) {
                 console.log('File Added Successfully.');
             }
             function fileError(error) {
                 console.log(error.statusText + "nn" + error.responseText);
             }
         }
 
         function getFileBuffer(file) {
             var deferred = $.Deferred();
             var reader = new FileReader();
             reader.onloadend = function (e) {
                 deferred.resolve(e.target.result);
             }
             reader.onerror = function (e) {
                 deferred.reject(e.target.error);
             }
             reader.readAsArrayBuffer(file);
             return deferred.promise();
         }
 
         function deleteFile(fileURL) {
             var deferred = $q.defer();
             $http.delete(fileURL, Utilities.deleteRequestHeader())
                          .then(function (response) {
                              console.log('Deleted the attachment.');
                              deferred.resolve(response);
                          }, function (error) {
                              deferred.reject(error);
                          });
             return deferred.promise;
         }
     };
 
     //Supporting function 
     function getEntityTypeFullName(listName) {
         return "SP.Data." + listName.replace(' ', '_x0020_') + "ListItem";
     }
 
     var module = angular.module("Mainapp");
     module.factory(serviceId, ['$http', '$q', 'Utilities', List_Context])
 }());
 

Main.js

 (function () {
     'use strict';
 
     var controllerId = 'Mycontroller';
     var app = angular.module("Myapp", []);
 
     var Mycontroller = function ($scope, $q, List_Context, Utilities) {
         function SaveData() {
             var updatingVals = {};
             updatingVals['Title'] = "TEST Title";
             var filesAdd = {};
             //Please refer previous article to know how to get attachment value in attachedFile scope variable
             //https://www.sharepointpals.com/post/Get-all-attachments-from-SharePoint-List-Item-using-AngularJS
             filesAdd = $scope.attachedFile;
             var listID = "BF6BCA2E5-12B5-452F-8EA6-B6789AF4CDEB";
             var listItemID = 10;
             var listName = "MyList";
             SP_WaitScreen();
             var promises = [];
             List_Context.updateListData(listID, listItemID, updatingVals, listName)
                     .then(function (value) {
                         //Please refer previous article to see how to get removeFile values - 
                         //https://www.sharepointpals.com/post/How-to-handle-multiple-file-selection-and-validation-on-input-file-type-using-AngularJS
                         angular.forEach($scope.removeFile, function (filePath, key) {
                             promises.push(List_Context.checkFileExistsAndRemove(filePath));
                         });
                     }, function (reason) {
                         SP_WaitScreen_Close();
                         window.open(window.parent.location.reload(true), "_parent", "");
                     });
         }        
 
         //OOTB Wait modal dailog
         function SP_WaitScreen() {
             SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () {
                 window.parent.eval("window.waitDialog = SP.UI.ModalDialog.showWaitScreenWithNoClose('Working on it...', '');");
             });
         }
         function SP_WaitScreen_Close() {
             if (window.frameElement != null) {
                 if (window.parent.waitDialog != null) {
                     window.parent.waitDialog.close();
                 }
             }
         }
     }
     app.controller(controllerId, Mycontroller);
     app.config(['$compileProvider', function ($compileProvider) {
         $compileProvider.aHrefSanitizationWhitelist(/^s*(https?|file|blob):/);
     }]);
 });
 
 <script type="text/javascript" src="../../../../SiteAssets/js/Scripts/jquery.min.js"></script>
 <script type="text/javascript" src="../../../../SiteAssets/js/Scripts/jquery.SPServices-2014.02.min.js"></script>
 <script type="text/javascript" src="../../../../SiteAssets/js/Scripts/angular.min.js"></script>
 <script type="text/javascript" src="../../../../SiteAssets/js/sppals/Controllers/Main.js"></script>
 
 <!--Services-->
 <script type="text/javascript" src="../../../../SiteAssets/js/sppals/Services/List_Context.js"></script>
 <script type="text/javascript" src="../../../../SiteAssets/js/sppals/Services/Utilities.js"></script>
 <div id="divNew" ng-app="Myapp">
     <ng-form id="EditForm" name="EditForm">
         <div ng-controller="Mycontroller">         
                                 <div>Attach Memo:</div>
                                 <div>
                                     <span id="attach">
                                         <input id="uploadFileID" type="file" ng-file-model="files" />
                                                                                 
                                         <p class="attach-Text" ng-repeat="file in attachedFile">
                                             <a target="_blank" href="{{file.ServerRelativeUrl}}" ng-href="{{file.ServerRelativeUrl}}">{{file.FileName}}</a>                                             
                                             <a title='Click to Remove' ng-click="removeFile(attachedFile, $index)">
                                                 <img class="deleteIcon" src='../../../../SiteAssets/img/Delete_icon.png' />
                                             </a>
                                         </p>                                        
                                     </span>                               
                                 </div>
             <input type="button" id="btnSave" ng-click="SaveButtonClick()" title="Click to Save" value="Save" />
         </div>
     </ng-form>    
 </div>
 

Happy Coding

Ahamed

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

Leave a comment