This repository has been archived by the owner. It is now read-only.

Multiple attachments using batch calls in SharePoint 2013 on-premise #381

Closed
CoderGeet opened this Issue Mar 21, 2017 · 13 comments

Comments

Projects
None yet
4 participants
@CoderGeet

CoderGeet commented Mar 21, 2017

[X ] Enhancement

[ ] Bug

[X ] Question

I have a requirement to attach multiple files to a list item in SharePoint. I know we have the batch api available with PnP. But since REST batch calls is available only for SharePoint Online and SharePoint 2016 On-Premise, I cannot use this api for doing batch operations in SharePoint 2013 On-premise.
Multiple upload is a very common requirement by customers. I can play around with recursive function calls and promises and try to work around with this. But my question is if I have to use pnp-js-core to achieve this, is there any recommended way of doing it.

Thanks!

@koltyakov

This comment has been minimized.

Collaborator

koltyakov commented Mar 21, 2017

Hi,

You are absolutely right that unfortunately there is no batch API in SP 2013.
Yet your task looks to be achievable with the use of standard Promise.all functionality. Yep, there will be numerous physical requests, yet the script can be pretty straightforward like:

var itemPnp = $pnp.sp.web.getList('/sites/dev01/Lists/Custom02').items.getById(101);

var promises = [
  itemPnp.attachmentFiles.add('Attachment 01.txt', 'Content123'),
  itemPnp.attachmentFiles.add('Attachment 02.txt', 'Content234'),
  itemPnp.attachmentFiles.add('Attachment 03.txt', 'Content567'),
  itemPnp.attachmentFiles.add('Attachment 04.txt', 'Content789')
];

Promise.all(promises).then(function(results) {
  console.log(results);
});
@CoderGeet

This comment has been minimized.

CoderGeet commented Mar 21, 2017

Hi Koltyakov,

Thank you so much for your reply. Unfortunately this will not work always as I am trying to update a single list item with all the attachments. Since the calls are async so there might be scenarios where I will get 409 Save Conflict error as all the updates are happening to the same list. I tried this approach and if I try to upload a bunch of files together then I do encounter this issue intermittently with 409 error code. :(

Thanks!

@patrick-rodgers

This comment has been minimized.

Contributor

patrick-rodgers commented Mar 21, 2017

@CoderGeet - @koltyakov is correct, you can use the promise.all - but based on something in gitter that might cause conflicts with adding the files to the list item as the promises will be firing simultaneously. So you can chain them using .then() as I discuss in a blog post. Let me think about adding support for this and see how it might fit.

@CoderGeet

This comment has been minimized.

CoderGeet commented Mar 21, 2017

Thanks Patrick. I will follow the blog post and do required changes to my code.

@CoderGeet

This comment has been minimized.

CoderGeet commented Mar 21, 2017

@koltyakov @patrick-rodgers : I am able to upload multiple items to a list by making recursive calls to add attachment using .then().
@patrick-rodgers : It will be awesome if we can have a wrapper method where pnp-js component takes care of the chaining and we simply pass a collection object as an input.
Thanks a lot :)

@patrick-rodgers

This comment has been minimized.

Contributor

patrick-rodgers commented Mar 21, 2017

So for this to work you'd have a method signature something like.

attachments.addMultiple(fileInfo: { name: string, content: string | Blob | ArrayBuffer}[]): Promise<void>

and a usage like:

let files = [
{ name: "File1.txt", content: "blah" },
{ name: "File2.txt", content: "blah" },
{ name: "File3.txt", content: "blah" }
];

attachments.addMultiple(files).then(_ => console.log("all done"));

Is that what you had in mind?

@patrick-rodgers

This comment has been minimized.

Contributor

patrick-rodgers commented Mar 21, 2017

Well, went ahead and added it. Have a look and let me know if that is indeed what you had in mind. #383

@patrick-rodgers

This comment has been minimized.

Contributor

patrick-rodgers commented Mar 21, 2017

Usage:

let files = [{
    name: "File5.txt",
    content: "balh"
}, {
    name: "File6.txt",
    content: "balh"
}, {
    name: "File7.txt",
    content: "balh"
}, {
    name: "File8.txt",
    content: "balh"
}]

pnp.sp.web.lists.getByTitle("ChoiceFieldList").items.getById(1).attachmentFiles.addMultiple(files).then(_ => {

    pnp.sp.web.lists.getByTitle("ChoiceFieldList").items.getById(1).attachmentFiles.get().then(files => {
        console.warn(files);
    })

});
@CoderGeet

This comment has been minimized.

CoderGeet commented Mar 21, 2017

@patrick-rodgers Awesome. That was exactly what I was looking for. Right now I am not having access to my SharePoint environment but will test it the first thing tomorrow. I am quite sure it will work like a charm. I will update after doing a testing tomorrow morning. Thanks for adding a wrapper method.

@CoderGeet

This comment has been minimized.

CoderGeet commented Mar 22, 2017

@patrick-rodgers My apologies for asking this dumb question but how do I get the updated package? When I try to install/update the sp-pnp-js package using npm it does not bring the updated files for me. I have the version 2.0.2 installed for sp-pnp-js.

@patrick-rodgers

This comment has been minimized.

Contributor

patrick-rodgers commented Mar 22, 2017

There isn't a way currently to get a new version until we do a monthly release. You can fork the library and build/package the dev branch yourself to test changes. I am also looking at how hard it would be to produce a beta release (unstable) off the dev branch. But just starting that work so likely not ready for a bit.

Going to close this as resolved as the change is merged to dev - will be part of the April release.

@CoderGeet

This comment has been minimized.

CoderGeet commented Mar 22, 2017

@patrick-rodgers That makes sense. Thanks a lot for working on this and providing a method to upload multiple files. Really appreciate that.

@PCASME

This comment has been minimized.

PCASME commented Jul 30, 2017

Would be interesting to have also the method deleteMultiple, don't you?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.