10

I'm working with SP2010's SP.js and I need to get all the attachments of a list item. As it's SP2010, I don't have access to SP.ListItem's attachmentFiles property. :(

The following code works for this purpose:

var attachmentFolder = clientContext.get_web().getFolderByServerRelativeUrl('/sites/MySite/Lists/MyList/Attachments/' + itemID);
var attachmentFiles = attachmentFolder.get_files();

clientContext.load(attachmentFiles);
clientContext.executeQueryAsync(
    function () {

        var myAttachments = [];
        for (var i = 0; currentItem = attachmentFiles.get_item(i) ; i++)
        {
            myAttachments.push({
                url: currentItem.get_serverRelativeUrl(),
                name: currentItem.get_name()
            });
        }
    },
    function(error) {
        alert("Something has failed magnificently! " + error);
    }
);

The issue is that if the list item has no attachments, sp.js throws a "File Not Found" exception into my error callback. Not pictured in the code sample I included, I'm requesting a few other things in this JSOM query, so my solution is unfortunately not as simple as assuming that an error being returned means that no attachments were found. I don't want my lack of attachments to screw up my other logic.

I tried using a method similar to the following:

var query = SP.CamlQuery.createAllItemsQuery();
query.set_folderServerRelativeUrl(folderServerRelativeUrl);
allItems = list.getItems(query);

but it always returns 0 results, even when attachments are present, so I'm assuming that this CAML query only works on folders that are part of a proper library, not backend folders.

I really don't want to have to make an extra request.

Any ideas?

8

Using SharePoint 2010 JSOM i would suggest the following approach to retrieve list item attachments:

  • determine whether List Item contains attachments or not via ListItem.Attachments property
  • in case if list List Item contains attachments, submit a second request to retrieve attachment files

Example

function getListItemAttachments(listTitle,itemId,success,error)
{
   var ctx = SP.ClientContext.get_current();
   var list = ctx.get_web().get_lists().getByTitle(listTitle);
   var item = list.getItemById(itemId);
   ctx.load(item);
   ctx.executeQueryAsync(
      function() {
          var hasAttachments = item.get_fieldValues()['Attachments'];
          if(hasAttachments){
              getAttachmentFiles(item,success,error);
          }
          else
            success([]);
      },
      error);
}



function getAttachmentFiles(listItem,success,error) {
    var ctx = listItem.get_context();
    var attachmentFolderUrl = String.format('{0}/Attachments/{1}',listItem.get_fieldValues()['FileDirRef'],listItem.get_fieldValues()['ID']);
    var folder = ctx.get_web().getFolderByServerRelativeUrl(attachmentFolderUrl);
    var files = folder.get_files();
    ctx.load(files);
    ctx.executeQueryAsync(
       function () {
          var attachments = [];
          for (var i = 0; file = files.get_item(i) ; i++)
          {
              attachments.push({url: file.get_serverRelativeUrl(), name: file.get_name()});
          } 
          success(attachments);      
    },
    error);
}

Usage

getListItemAttachments('Requests',1, 
    function(attachmentFiles){
       console.log(attachmentFiles);
    },
    function(sendera,args){
       console.log(args.get_message());
    });
  • 1
    I really didn't want to make two requests, but it looks like this might be the only way. :/ – Joshua Walsh Feb 18 '15 at 22:34
1

Check if your list does have attachments enabled?

This can be done using Rest API

/getByTitle('<ListName>')/items?$filter=substringof('Item', Title)
&$select=AttachmentFiles,Title&$expand=AttachmentFiles&$top=4&$orderby=Title"
  • 1
    Does this work for 2010? The question is targeted to 2010 – Robert Lindgren Feb 20 '15 at 9:32
  • Sorry if I wasn't clear, the list does have attachments enabled, but if an item in the list does not have any attachments then get_folder errors out and breaks that entire query. @VadimGremyachev has already provided an elegant way to do what I wish to achieve in 2 requests, I'd love to see how to do it in one though. – Joshua Walsh Feb 21 '15 at 9:44
  • For 2010 the following edit works for getting all attachments: /<ListName>?$filter=substringof('Item', Title)&$select=Attachments&$expand=Attachments – Toadmyster Nov 7 '16 at 18:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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