Skip to main content

File attach (POST) to SharePoint 2013 List (custom) using Angular JS via REST API

Following describes how to upload attachment to SharePoint 2013 custom list using Angular JS.

Note: You can be consumed the JSOM libraries to achieve this, but there is limitation of 1.5 Mb. Better approach would be consuming exposed REST API (SharePoint OOTB) which allowed up to 2 Gb of file to attached using client side scripts i.e. Angular JS. .

Here I have used the “Angular File Upload” which capable of doing more tasks other than basic HTML input file control. By consuming this we can attach multiple files either to the list and etc. You can be found the information on how to include this module to your Angular view in following link.

Use package manager command to install the scripts.
For bower  -->        bower install angular-file-upload

For nugget -->       npm install angular-file-upload

It requires file buffer array to POST (save) our attachment via REST API, browsers FileReader API is required to use. Its available with almost all common browsers. You need to ensure that is available before in your environment to consume this.

HTML5 FileReader API

Its an API exposed to handle with read contents of BLOB or files. Its supported in most of the latest versions of browsers. If you further required information

View (HTML)

[code lang="html" highlight="4" title="Angular View"]
<div ng-app="app" ng-controller="FileUpload as vm" ng-cloak>
<div class="row">
<span id="btn" class="btn btn-default">Select file(s)</span>
<!-- Example: nv-file-select="" uploader="{Object}" options="{Object}" filters="{String}" -->
<input id="fileUploader" type="file" nv-file-select="" uploader="vm.uploader" multiple style="visibility:hidden;" />
{{ vm.uploader.queue.length }} files attached.
<div class="row">
<div uploader="vm.uploader" filters="queueLimit, customFilter">
<table class="table">
<tr ng-repeat="item in vm.uploader.queue">
<td wrap>{{ }}</td>
<button type="button" class="btn btn-danger-focus btn-xs" ng-click="item.remove()">
<span class="glyphicon glyphicon-trash"></span> Remove



[code lang="javascript" collapse="true"]

(function () {
'use strict'

.controller('FileUpload', ['FileUploader', 'AttachmentSvc', function (FileUploader, AttachmentSvc) {

var vm = this
, filesObj = [];

function init() {
// Check for FileReader API (HTML5) support.
if (!window.FileReader)
console.log(&quot;[Debug] This browser does not support the FileReader API.&quot;); = saveFile;

vm.uploader = new FileUploader({
url: ''//url for file upload

name: 'customFilter',
fn: function (item /*{File|FileLikeObject}*/, options) {
//constraint for 10 files
return this.queue.length &lt; 10;

// file callbacks
vm.uploader.onAfterAddingFile = function (fileItem) {
//file added to the object array
console.log(&quot;Files object&quot;, filesObj);

vm.uploader.onAfterAddingAll = function (addedFileItems) {
//'onAfterAddingAll', addedFileItems);
//this will be called after adding all
//by default calls every time after file adding

//Code for SharePoint upload
function saveFile(event) {

//get file selected
var file = filesObj[0]._file;

//convert to arraybuffer
.then(function (data) {
if (data != null)
AttachmentSvc.saveFile(data,, 1);

.catch(function (err) {
console.log(&quot;Error on getting file array buffer&quot;)




[code lang="javascript"]

(function () {

'use strict'

.factory('AttachmentSvc', ['$q', '$resource', '$window', '$http', function ($q, $resource, $window, $http) {
var service,
ListName = 'test',
serviceId = 'AttachmentSvc';//name of document library

service = {
saveFile: saveFile,
getFileBuffer: getFileBuffer

function init() {
console.log(&quot;Initiated..&quot;, serviceId);

return service;

//save file to custom list
function saveFile(fileArrBuffer, fileName, itemId) {
var deferred = $q.defer();
//POST request
method: 'POST',
url: spContext.webUrl + '/_api/web/lists/getbytitle(\'' + ListName + '\')/items(' + itemId + ')/AttachmentFiles/add(FileName=\'' + fileName + '\')',
headers: {
'Accept': 'application/json;odata=verbose',
'Content-Type': undefined,
'X-RequestDigest': spContext.securityValidation,//TODO: provide your digest value here,else it will throw security issues
data: new Uint8Array(fileArrBuffer),
transformRequest: []
}).then(function successCallback(data) {
// this callback will be called asynchronously
console.log('Successfully saved.', data, serviceId, false);
}, function errorCallback(error) {
// called asynchronously if an error occurs
console.log('Failed to save!!!.', error, serviceId, false);
return deferred.promise;

// getting file array buffer
function getFileBuffer(file) {
var deferred = $q.defer();
var reader = new $window.FileReader();
reader.onloadend = function () {
reader.onerror = function () {
return deferred.promise;


Hope this helped you! Don't forget to share with others @kushanlahiru


Further references


  1. Hi,

    I have used above code to insert an attachment to list item, but I am getting an error message as file is not readable in getFilebuffer method.

    When I am debugging attachment has been added to list item,same is not working while not debugging.

  2. Route cause may be you not passing a valid file to to file array buffer generator. I could not mention exactly what is the issue with this statement. If you could describe more detail, I will help you out for sure.

    Thanks for sharing!

  3. Hi Kushan,

    I am using above code to save multiple attachments in to list,I am getting error message as 409 conflict error for some attachments.

    suppose I have 10 attachments to save,for 2 or 3 attachments I am getting error message 409 conflict. After spending lot of time If I call saving attachment function in attachment success then its working fine.

    For me 10 attachments is not fixed it will be dynamic, so I can't write 10 then functions, for this I have used ajax call with async false.

    Please suggest me best approach which will increase performance.

  4. Hi There. This is a great article. But I too am having a few issues.

    Do you have a gitjhub repo I could reference please?

  5. I have not hosted this code in a GitHub since since required to be more general. If I know your issue, then I could be able to help you! @KushanLahiru

  6. Hi Bhanu,

    For first question: You may try with different file set for files which conflicting. Then also you get this issue, there may be not issue with the code may be some issue with a environment or with the code. Then there is more to work with drilling down into.

    For second question:first concern is if you use Angular then strict to its way to doing things, else maintenance issues. But with your method of doing network traffic may be higher but if your scenario facilitates large network bandwidth there wont be issue since with allowing async.

    Hope I answer you, and keep in touch for more inspirations!

  7. […] File attach (POST) to SharePoint 2013 List (custom) using Angular JS via REST API […]

  8. Hi,

    I using the above code, added the js and angular reference in my file. after that I have added the HTML and js code but when I run this code in browser it gives me below errors in console , Please help.

    angular.js:38Uncaught Error: [$injector:nomod]
    angular.js:38 Uncaught Error: [$injector:modulerr]

    Please suggest, what am I doing wrong here?

  9. Hi, I am using the above code but getting some errors. I have added the Js and angular reference and added the HTML and script code in my page but when I run this code in browser (Chrome) I am getting below errors:
    Uncaught Error: [$injector:nomod]
    Uncaught Error: [$injector:modulerr]

    please Suggest What am I doing wrong here.

  10. Hi Kaushan,

    I'm new to Angular..can you send this full solution to learn..

  11. Hi Kushan,

    Thank you for posting this. Quick question, can you give us an example of the url in your controller:

    vm.uploader = new FileUploader({
    url: ''//url for file upload

    Please let us know.

    Thank you!

  12. Thanks for motivations Jay. It was and initialization of FileUploader and does not matter whether it kept blank as for my code.

    If you not willing to consume service like in my implementation, you can be used the REST endpoint. As example as below;

    vm.uploader = new FileUploader({
    url: '/{userId}/files'

    Happy for the opportunity to help you. Keep following for updated via @kushanlahiru

  13. We have tried same code but using it we are able to upload single file having size 33MB. If I try to upload file having size more than 33 MB then it is not saving in library and we getting error google chrome is running out memory while trying to display this webpage..

  14. It depends on the configuration of REST endpoint. Here I have used SharePoint and supports up to 2GB and its working fine for me.

  15. I also have the same problem with multiple file attachment via loop.
    Did you find any better solution to run $http calls synchronously (or in chain) without using jQuery?

  16. User Angular here and no JQuery! I'm not clear where you exactly need to arrive at. @KushanLahiru

  17. Hi Kushan,
    Great Article. But I do not understand what is spContext.webUrl here? When I tried this code, I keep getting message as that spContext is undefined. Please, can you help, what I am missing?

  18. Follow and add this script. You will be find your destiny

  19. I have used your code for posting to folder in document library and it works !!!!


Post a Comment

Popular posts from this blog

Turn off/ Hide Details panel/ Information Panel on modern SharePoint lists

Not always we require to show changes done by other which is a mandatory feature in SharePoint online.  What is details pane (aka. Information Pane)? Detail pane/ Information shows information regarding the document if you selected a one or its showing recent changes within a list or library. Follow link to Microsoft documentation about details pane. Bad news: Until Microsoft listen to User Voice , there is no straightforward way to enable disable this even you don't want. Good news: We could write a SharePoint framework extension to hack styles until Microsoft give us a permanent solution. How? I found this sample project (Inject CSS into modern SharePoint pages with React) which could reuse to our purpose. Thanks to Hugo for saving my time.  Steps to awesomeness:  Clone the project Resolve dependencies >  npm i Bundle >  gulp bundle --ship Package >  gulp package-solution --ship Upload package into SharePoint App catalog  

📢 Update -Top 10 Microsoft Teams questions from customers around the world

Over the last 4 months, we’ve traveled to 9 countries on Microsoft Ignite | The Tour meeting and speaking with users like you about Microsoft Teams. The insights and feedback at every location has been invaluable — Thank you. During our travels, there have been 10 questions that have repeatedly surfaced. Below are all of the questions — including the answers too, of course!   Can you restrict access to a specific channel in a team? What are best practices for governance, specifically around team creation, naming, and retention? Can I add guests to my team? If so, how? How does external access/federation work? How is this different to guest access? What functionalities do I get in a hybrid environment? Is Teams available for on-prem environments? How do I configure Direct Routing in Microsoft Teams? Why should I move from Skype for Business to Teams? How do I make this transition? I have existing SharePoint sites that I would like to bring into Teams. Can I do that? I need t

Eliminate Duplicates in Microsoft Flow and Azure Logic Apps

There is no straight forward method or Microsoft Flow action  to eliminate values in a collection like Microsft Excel (as of March 2019). This little hack will help you to eliminate/ remove duplicates and create a collection of unique values. Sample scenario: Need to send daily summarized notification to assigned approved with pending approval items. Sample workflow: Initialize an array Iterate collection of data and append items that are not there in the filtered array Side note: This won't be an option to consider if you too concerned about the performance of the workflow but for the time being its an option to consider.