skip to Main Content

For all of the convert to base 64 functions I have found on stack overflow it requires using a promise. So i create a function that generates a new promise and I await on it for the response then return that. I use this function for all the files I am converting to base64 however for some reason when I get to my backend with the request it still says its a object.promise so I am assuming the await is not working correctly.

                getBase64 : async (file) => {
                let data = await new Promise((resolve, reject) => {
                    const reader = new FileReader();
                    reader.readAsDataURL(file);
                    reader.onload = () => resolve(reader.result);
                    reader.onerror = (error) => reject(error);
                })
                return data
            },
            submitHistoricalPreprint() {
                
                if (this.$refs['AddHistoricalPreprintForm'].validate()) {

                    let form = new FormData()

                    this.historicalPreprintDocs.forEach((round, index) => {

                        form.append(`data[${index}].ppid`, this.selectPPID.PPID)

                        form.append(`data[${index}].round`, round.round)

                        if (round.preprint) {
                            form.append(`data[${index}].preprint.fileName`, round.preprint.name)
                            form.append(`data[${index}].preprint.content`, this.getBase64(round.preprint))
                        } else {
                            form.append(`data[${index}].preprint`, null)
                        }

                        round.supportingDocumentation ? round.supportingDocumentation.forEach((file, index2) => {
                            form.append(`data[${index}].supportingDocumentation[${index2}].fileName`, file.name)
                            form.append(`data[${index}].supportingDocumentation[${index2}].content`, this.getBase64(file))
                        }) : form.append(`data[${index}].supportingDocumentation`, null)

                        if (round.oactQuestions) {
                            form.append(`data[${index}].oactQuestions.fileName`, round.oactQuestions.name)
                            form.append(`data[${index}].oactQuestions.content`, this.getBase64(round.oactQuestions))
                        } else {
                            form.append(`data[${index}].oactQuestions`, null)
                        }

                        round.cmcsResponses ? round.cmcsResponses.forEach((file,index2) => {
                            form.append(`data[${index}].cmcsResponses[${index2}].fileName`, file.name)
                            form.append(`data[${index}].cmcsResponses[${index2}].content`, this.getBase64(file))

                        }) : form.append(`data[${index}].cmcsResponses`, null)

                        if (round.stateResponses) {
                            form.append(`data[${index}].stateResponses.fileName`, round.stateResponses.name)
                            form.append(`data[${index}].stateResponses.content`, this.getBase64(round.stateResponses))
                        } else {
                            form.append(`data[${index}].stateResponses`, null)
                        }

                        if (round.approvalLetter) {
                            form.append(`data[${index}].approvalLetter.fileName`, round.approvalLetter.name)
                            form.append(`data[${index}].approvalLetter.content`, this.getBase64(round.approvalLetter))
                        } else {
                            form.append(`data[${index}].approvalLetter`, null)
                        }
                    })

                    axios({
                        method: 'post',
                        url: window.location.origin + '/Preprint/UploadHistoricalReview',
                        data: form,
                        headers: {
                            'Content-Type': 'multipart/form-data',
                            "RequestVerificationToken": document.forms[0].querySelector('input[name="__RequestVerificationToken"]').value,
                        }
                    }).then(response => {
                        this.historicalPreprintDocs = [{
                            "round": 1,
                            "preprint": null,
                            "supportingDocumentation": [],
                            "oactQuestions": null,
                            "cmcsResponses": [],
                            "stateResponses": null,
                            "approvalLetter": null,
                        }]
                        this.$refs['AddHistoricalPreprintForm'].reset();

                    }).catch(error => {
                        if (error.response.status == 401 || error.response.status == 402 || error.response.status == 403) {
                            window.location.href = error.response.headers.expiredtokenredirecturi
                        }
                        console.log(error.response.data.error);
                    });
                }
            },

2

Answers


  1. You don’t need a promise just to convert to base64.

    Try:

    str = "The quick brown fox jumps over the lazy dog";
    b64 = btoa(unescape(encodeURIComponent(str)));
    str = decodeURIComponent(escape(window.atob(b64)));
    

    See demo/examples in this other answer:

    How can you encode a string to Base64 in JavaScript?

    Login or Signup to reply.
  2. Using an asynchronous approach for this is fine, you just need to ensure that you handle your getBase64 function call asynchronously as well. Doing a form.append with the return value of getBase64 will append a promise, rather than the encoded value, so you need to await this call or use a .then. Example using async/await:

    async submitHistoricalPreprint() {
        ...
        try {
            await Promise.all(this.historicalPreprintDocs.map(async (round, index) => {
                ...
                form.append(..., await this.getBase64(...));
    
                round.supportingDocumentation ? await Promise.all(round.supportingDocumentation.map(async (file, index2) => ...)) : ...;
                ...
            });
        } catch (err) {
            // handle file encoding failures
        }
        ...
    }
    

    Note: It’s important that you use a Promise.all with a .map and an async callback (or a function that returns a promise) instead of the original .forEach so that you can properly handle any promise rejections. Additionally, doing the Promise.all with the .map allows for I/O concurrency, whereas a regular for...of loop with awaits would force them to be handled sequentially

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search