3

By doing online research, I wrote code to create list item in JavaScript for SharePoint 2013 REST API, code is working fine.

I have also wrote code to upload attachments for particular item. The problem is, I need to make two separate calls to make this happen.

What I am trying to achieve is, create list item with multiple attachments in single HTTP call.

2 Answers 2

1

Hi try using below script block

function addItem(){

try{

    var data = {
        __metadata: { 'type': 'SP.Data.ListNameListItem' },
        Title: "Title"         
    };

   addListItem("ListName",$("#__REQUESTDIGEST").val(),data).then(function(data){

         if (document.getElementById("inputFile").files.length === 0) {                     
                    alert("Your item has been submitted successfully!");                        
           }       
           else
           {
               //File Upload
                var itemId =  data.d.ID;   
                var fileInput = $('#inputFile');
                var fileCount = fileInput[0].files.length;  
                var fileArray = [];

                for(var i=0;i<fileCount;i++)
                {
                    fileArray.push(fileInput[0].files[i]);
                }                               
                uploadFileSP("ListName", itemId, fileArray, fileCount);
           }
   },function(err){
       alert("Your item has not been submitted successfully!");
   });  
}
catch(error)
{
    alert("Your item has not been submitted successfully!");
}                               
}


function addListItem(listName,  requestDigestValue, data) {  

return $.ajax({
    url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('" + listName + "')/items",
    type: "POST",
    headers: {
        "accept": "application/json;odata=verbose",
        "X-RequestDigest": requestDigestValue,
        "content-Type": "application/json;odata=verbose"
    },
    data: JSON.stringify(data)
});
}

function getFileBuffer(file) {
var deferred = $.Deferred();
var reader = new FileReader();
reader.onload = function (e) {
    deferred.resolve(e.target.result);
}
reader.onerror = function (e) {
    deferred.reject(e.target.error);
}
reader.readAsArrayBuffer(file);
return deferred.promise();
}

function uploadFileSP(listName, id, fileArray, fileCount) {
var FilesCount = 0;
var deferred = $.Deferred();
var uploadStatus = "";
var file = fileArray[0];
var getFile = getFileBuffer(file);

getFile.done(function (buffer, status, xhr) {
    var bytes = new Uint8Array(buffer);
    var content = new SP.Base64EncodedByteArray();
    var queryUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/lists/GetByTitle('" + listName + "')/items(" + id + ")/AttachmentFiles/add(FileName='" + file.name + "')";
    var uploadCount = 0;
    $.ajax({
        url: queryUrl,
        type: "POST",
        processData: false,
        contentType: "application/json;odata=verbose",
        data: buffer,
        headers: {
            "accept": "application/json;odata=verbose",
            "X-RequestDigest": $("#__REQUESTDIGEST").val(),
            "content-length": buffer.byteLength
        },
        success: function (data) {
            FilesCount++;
            uploadStatus = FilesCount;
            fileArray.shift();
            if (fileArray.length > 0) {
                uploadFileSP("ListName", id, fileArray, fileArray.length);
            }
            else {
              alert ("Your item has been submitted successfully!");                    
            }
        },
        error: function (err) {                
            alert("Idea has been submitted but some files failed to upload.");                
        }
    });
    deferred.resolve(uploadStatus);
});

getFile.fail(function (err) {
    deferred.reject(err);
});
return deferred.promise();
}
5
  • I almost did the same way. But my main aim is not to make two HTTP call. I want to create item and upload attachments in one REST API call itself.
    – salah9
    Dec 23, 2017 at 17:51
  • 2
    You cannot upload attachments for new item in a single REST call. Because uploading attachment needs item ID for the new item it does not exist until the item is created. So, Technically we can only start upload attachment on the success method of item create call... Dec 24, 2017 at 3:00
  • Thanks for sharing that piece of knowledge. But is there any way to make single call and upload all attachments together?. In the above code, If user is attaching 5 files to an item, then we are making total number of 6 calls to user. I am looking for a solution were first call is made create item and second call is made to upload all attachment.s
    – salah9
    Dec 25, 2017 at 2:57
  • 1
    For multiple upload attachments call, you can refer the demo below: c-sharpcorner.com/article/…
    – Jerry
    Dec 25, 2017 at 8:35
  • What are the lines "var bytes = new Uint8Array(buffer);" and "var content = new SP.Base64EncodedByteArray();" for?
    – Paul Vu
    May 15, 2020 at 14:01
0

The accepted answer asks user to authenticate for me.

This code which uses SPServices, works fine for me:

function AddAttachments(itemId, listName) {
var file = $("#videoUpload")[0].files[0];
var getFileBuffer = function (file) {

    var deferred = $.Deferred();
    var reader = new FileReader();

    reader.onload = function (e) {
        deferred.resolve(e.target.result);
    }

    reader.onerror = function (e) {
        deferred.reject(e.target.error);
    }

    reader.readAsArrayBuffer(file);

    return deferred.promise();
};

getFileBuffer(file).then(function (buffer) {
    var bytes = new Uint8Array(buffer);
    var content = new SP.Base64EncodedByteArray(); //base64 encoding
    for (var b = 0; b < bytes.length; b++) {
        content.append(bytes[b]);
    }

    $().SPServices({
        operation: "AddAttachment",
        listName: listName,
        listItemID: itemId,
        fileName: file.name,
        attachment: content.toBase64String()
    });

});
}

Credits to the author: https://sympmarc.com/2014/05/27/uploading-attachments-to-sharepoint-lists-using-spservices/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.