javascriptbase64filereader

Having trouble getting a Base64 string from FileReader


I'm attempting to pass a file from an file input field's file list through FileReader and get the Base64 string to pass to the server via axios. The FileReader's onload function seems to get the string, but it evidently loses the string before it is returned. So, the value is undefined when I try to append it to the form data.

I'm told this is an asynchronous function, but I'm not sure where to await the promise. Can someone tell me what I'm doing wrong here?

const handleSubmit = async (e) => {
        e.preventDefault()

        const formData = new FormData()

        // FILE READER -- DOES NOT WORK
        const getImageFile = () => {
            return new Promise(resolve => {
                const reader = new FileReader()
                reader.onload = function () {
                    const imageFile = reader.result
                    // console.log(`IMAGE FILE:\n ${imageFile}`) // imageFile IS NOT UNDEFINED HERE, BASE64 STRING
                }
                reader.readAsDataURL(document.getElementById("image").files[0])
            })
        }
        ////////////////////////////////
        const imageFile = await getImageFile()
        
        Array.from(document.getElementById("form").elements).forEach(element => {           
            switch (element.name){
                case "image":
                    formData.append(`${element.name}`, imageFile) // UNDEFINED. WHY?
                    break
                case "submit":
                    break
                default:
                    formData.append(`${element.name}`, element.value)
            }
        })

        console.log([...formData])

        try {
            const response = axios.post('http://localhost:4000/uploadShow', formData)
            console.log(response)
        } catch (e) {
            console.log(e)
        }
    }

Solution

  • You have to create the promise yourself

    const getImageFile = () => {
      return new Promise(resolve => {
        const reader = new FileReader()
        reader.onload = function () {
          resolve(reader.result)
        }
        reader.readAsDataURL(document.getElementById("image").files[0])
      })
    }
    
    const handleSubmit = async (e) => {
    // ...
      const imageFile = await getImageFile()
    // ...