1

Some items in list can have more than one attachment so I want some method downloading all these files with one click event.

this is download urls,

private showDetail(title_:string, content_:string,  attachments_:any ): void {
    var fileUrls = [];
    if(attachments_.length > 0){
      attachments_.map((attachment:any, index:number)=>{
        fileUrls.push(this.props.siteUrl + attachment['ServerRelativeUrl'])
      })
      this.setState({fileUrls:fileUrls });
    }

I also tested url it works but I need to download all files here is my download function, its spfx project:

private getAttachment(): void {
    var fileUrls = this.state.fileUrls;
    fileUrls.map((url:string, i:number)=>{
      this.props.httpClient.get(url,SPHttpClient.configurations.v1)
            .then((response: Response)  => {
              return response.json();
            })
            .then((response: any): void => {
              this.setState({
                status: `Successfully loaded ${response.value.length} items`,
                items: response.value
              });
            }, (error: any): void => {
              this.setState({
                status: 'Loading all items failed with error: ' + error,
                items: []
              });
            });
      });
  }

I am able to see these files in network as below; enter image description here how can I download these as files ?

1 Answer 1

4

Actually, this has got nothing to with SPFx.

HTTP does not support more than one file download at once. So you can create a temporary set of hidden iframes, initiate download by GET or POST inside of them, wait for downloads to start and remove iframes or create an anchor tag with download attribute and then use the click event.

Below have presented both the approaches

Approach 1 - using anchor tag's download attribute (easier way)

private getAttachment(): void {

var fileUrls = this.state.fileUrls;

var link = document.createElement('a'); //create anchor tag

link.setAttribute('download', null); //set attribute to download
link.style.display = 'none'; //make sure its hidden

document.body.appendChild(link); //append it to html 

for (var i = 0; i < fileUrls.length; i++) 
{
    link.setAttribute('href', fileUrls[i]);  //set the url to that of list attachment
    link.click(); //use the click event to download files
}

document.body.removeChild(link); //remove the anchor after download complete

fileUrls.map((url:string, i:number)=>{
  this.props.httpClient.get(url,SPHttpClient.configurations.v1)
        .then((response: Response)  => {
          return response.json();
        })
        .then((response: any): void => {
          this.setState({
            status: `Successfully loaded ${response.value.length} items`,
            items: response.value
          });
        }, (error: any): void => {
          this.setState({
            status: 'Loading all items failed with error: ' + error,
            items: []
          });
        });
  });
}

Approach 2 - using hidden iframes (needs jQuery)

private getAttachment(): void {

var fileUrls = this.state.fileUrls;

for(var i=0; i<fileUrls.length; i++) 
{
 var iframe = $('<iframe style="visibility: collapse;"></iframe>');
 $('body').append(iframe);
 var content = iframe[0].contentDocument;
 var form = '<form action="' + fileUrls[i] + '" method="GET"></form>';
 content.write(form);
 $('form', content).submit();
 setTimeout((function(iframe) {
   return function() { 
     iframe.remove(); 
   }
 })(iframe), 2000);
}

fileUrls.map((url:string, i:number)=>{
  this.props.httpClient.get(url,SPHttpClient.configurations.v1)
        .then((response: Response)  => {
          return response.json();
        })
        .then((response: any): void => {
          this.setState({
            status: `Successfully loaded ${response.value.length} items`,
            items: response.value
          });
        }, (error: any): void => {
          this.setState({
            status: 'Loading all items failed with error: ' + error,
            items: []
          });
        });
  });
}

Reference - Download multiple files with a single action

Note - I tested this in constructor method and it works for me, so I think it should work in your getAttachment method. Have tested this in chrome only. It first asks me whether i should allow multiple downloads and when I click Ok, tt opens the standard save file popup and when I click OK, it saves the file.

2
  • this answer like wikipedia documentation, thanks I am on it Feb 4, 2017 at 12:38
  • only thing; files downloading as "null.jpg" and "null(1).jpg". not with real names. couldnt figure what cause this Feb 4, 2017 at 12:58

Your Answer

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

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