Вернуть zip-файл JSZip в React - PullRequest
0 голосов
/ 06 мая 2020

У меня есть функция, которая заархивирует файл, но она возвращает обещание. Я попытался реализовать это: jszip stackoverflow , но он по-прежнему возвращает нерешенное обещание.

Я не очень знаком с обещаниями и совсем не знаком с jsZIP - как мне получить эта функция для возврата заархивированного файла?

const getZip = (url) => {
        setLoadingStatus('zipping...')
        let zip = new JSZip();
        console.log("TYPOF URL", url, typeof url)
        zip.file("Report", url)
        var promise = null;
        if (JSZip.support.uint8array) {
        promise = zip.generateAsync({type : "uint8array"}).then(content => {
            saveAs(content, "Report.zip");
          });
        } else {
        promise = zip.generateAsync({type : "string"}).then(content => {
            saveAs(content, "Report.zip");
          });
        }
        console.log("TYPEOF PROMISE", promise, typeof promise) //typeof is always promise
        return promise
    }

С asyn c await:

    async function getZip(url){
    setLoadingStatus('zipping...')
    let zip = new JSZip();
    console.log("TYPOF URL", url, typeof url)
    zip.file("Report", url)
    var content = null;
    if (JSZip.support.uint8array) {
        content = await zip.generateAsync({type : "uint8array"}).then(content => {
            saveAs(content, "Report.zip");
          })
    } else {
        content = await zip.generateAsync({type : "string"}).then(content => {
            saveAs(content, "Report.zip");
          })
    }
    return content
}

Функция, которая вызывает getZip ():

const createURL = useCallback((node, reportHeight, reportWidth, imgHeight) => {

        domtoimage.toJpeg(node, {width: reportInViewerRef.current.offsetWidth, height: reportInViewerRef.current.scrollHeight})
    .then(function (dataUrl) {
        const pdf = new jsPDF('p', 'px', [reportWidth, imgHeight]);
        setLoadingStatus('pdf created')
        pdf.addImage(dataUrl, 'JPEG', 0, -12, reportWidth, reportHeight );
        setLoadingStatus('image added')
        let fileName = getUniqueFilename()
        let base64pdf = getZip(btoa(fileName, pdf.output()));
        console.log("ZIP FILE =================", base64pdf)
        let storageRef = firebase.storage().ref();
        setLoadingStatus('uploading...')
        let fileLocation = '/pdfs/' + fileName + '.zip'
        let reportPdfRef = storageRef.child(fileLocation);
        reportPdfRef.putString(base64pdf, 'base64').then(function() {
            console.log('Uploaded a data_url string!', reportPdfRef,
            reportPdfRef.getDownloadURL().then(function(url) {
                setLoadingStatus('linking...')
                setTemplateParams({
                    to: sessionData.customerEmail,
                    customers: name, 
                    adviser: adviserFullName,
                    adviserEmail: adviserEmail,
                    adviserAvatar: adviserAvatar,
                    content: url

                }) 
                firebase
                .firestore()
                .collection('sessions')
                .doc(sessionData.id)
                .update({
                    'pdfDownloadURL': url
                }).then(function() {
                    setLoadingStatus('sending email')
                    setSendingEmail(false);
                  });
              }).catch(function(error) {
                switch (error.code) {
                  case 'storage/object-not-found':
                        console.log("FILE DOES NOT EXIST")
                    break;
                  case 'storage/unauthorized':
                        console.log("USER DOES NOT HAVE PERMISSION TO ACCESS THIS FILE")
                    break;

                  case 'storage/canceled':
                        console.log("USER CANCELLED THE UPLOAD")
                    break;
                  case 'storage/unknown':
                        console.log("SERVER ERROR")
                    break;
                }
              })
            )
          });
        })
        .catch(function (error) {
            console.error('oops, something went wrong!', error);
        });
}, [])

1 Ответ

1 голос
/ 06 мая 2020

Поскольку создание zip-архива является асинхронным, c обработка кода также должна быть асинхронной c. Сделайте обработчик createURL asyn c и await zip внутри него:

const createURL = useCallback(async (node, reportHeight, reportWidth, imgHeight) => {
    try {
        const dataUrl = await domtoimage.toJpeg(node, {width: reportInViewerRef.current.offsetWidth, height: reportInViewerRef.current.scrollHeight})
    } catch (error) {
        return console.error('oops, something went wrong!', error);
    }

    // ... you can use dataUrl from here

    let base64pdf = await getZip(btoa(fileName, pdf.output()));

    // ... do something with the zip file
}

Вообще говоря, если функция asyn c возвращает что-то, код, использующий ее, также должен быть asyn c.

...