I have two functions here that takes an array of file keys, and passes it to a download function that will download each file individually from aws s3.
I would like to have all the files together in one zip folder and just download that one zip folder, so that all the files are together.
Questions:
1st How would I first set the directory to save the files to?
2nd How would I put all the files that are being downloaded in to one zip folder, then download the zip folder?
any help or insight is greatly appreciated.
current code
async function handleDownloadClick(event) {
event.preventDefault();
const imagesAsArray = [...imagesUploaded];
for (let i = 0; i < imagesAsArray.length; i++) {
await DownloadFile(imagesAsArray[i]);
}
}
async function DownloadFile(fileToDownload) {
const filename = `${fileToDownload.key}`;
const result = await Storage.get(fileToDownload.key, {download: true})
console.log(result)
let mimeType = result.ContentType
let fileName = fileToDownload.key.split(`${job.jobId},/`)
console.log(fileToDownload.key)
try {
let blob = new Blob([result.Body], {type: mimeType})
//downloading the file depends on the browser
//IE handles it differently than chrome/webkit
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName)
} else {
let objectUrl = URL.createObjectURL(blob);
let link = document.createElement('a')
link.href = objectUrl
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
} catch (exc) {
console.log("Save Blob method failed with the following exception.");
console.log(exc);
}
}
Updated Code doing what I needed it to do
figured I would share my solution, as i've seen alot of questions about this, but not many helpful answers.
using JSZip: https://stuk.github.io/jszip/
using saveAs from fileSaver.js: https://github.com/eligrey/FileSaver.js
First: it loops through downloading each file individually from s3, creates a blob, and puts each blob/file into a "folder".
Second: after each file has been downloaded from s3, it will then use the saveAs method to download/save the zipped folder.
function NewEditInfo(props) {
const [job, setJob] = useState([]);
const [imagesUploaded, setImagesUploaded] = useState(null);
//initialize jsZip
var JSZip = require("jszip");
let zip = new JSZip();
let photoZip = zip.folder(`${job.streetAddress}`);
useEffect(() => {
//// API call to load job info from dynamo db
function loadJob() {
return API.get("api name", "/tablename/tableinfo", {
'queryStringParameters': {jobId: props.match.params.id}
});
}
/// onload function to load job info and get a count of files
async function onLoad() {
try {
const job = await loadJob();
setJob(job[0])
const ImagesUploaded = await Storage.list(`${job[0].jobId}`);
setImagesUploaded(ImagesUploaded);
} catch (e) {
alert(e);
}
}
onLoad();
}, [props.match.params.id,]);
/// On download button click, loop through / download images using the key given from storage.list in onload function
async function handleDownloadClick(event) {
event.preventDefault();
const imagesAsArray = [...imagesUploaded];
for (let i = 0; i < imagesAsArray.length; i++) {
await DownloadFileFromS3(imagesAsArray[i]);
}
/// waits for "await DownloadFileFromS3, then executes the save as which saves the zipped folder created in "DownloadFileFromS3"
zip.generateAsync({type:"blob"})
.then(function(content) {
saveAs(content, `${job.streetAddress}`);
});
}
/// download each file from s3 and put it in the zip folder
async function DownloadFileFromS3(fileToDownload) {
const result = await Storage.get(fileToDownload.key, {download: true})
let mimeType = result.ContentType
let fileName = fileToDownload.key
let blob = new Blob([result.Body], {type: mimeType})
photoZip.file(fileName[1], blob)
}
return(
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton/>
</IonButtons>
<IonTitle>Download Images</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">
<IonButton onclick={handleDownloadClick}> download </IonButton>
</IonContent>
</IonPage>
);
}
export default withRouter(NewEditInfo);