[FIXED] JavaScript fetch POST request to Flask App Issue

Issue

I have a React frontend that I’m trying to setup to send a POST request with a file to upload to my Flask backend server. I went through this article to set it up, but I’m not seeing anything (or I’m getting errors) in the backend logs when troubleshooting/logging the request.<methods> (i.e. request.data, request.form, request.get_json(force=True), etc.)

Here is the frontend code:

const submitArticle = (e) => {
    e.preventDefault()
    let data = new FormData()
    data.append("title", article.title)
    data.append("content", article.content)
    data.append("image", article.images[0])
    data.append("start_date", article.start_date)
    data.append("expiration_date", article.expiration_date)
    let fetchOptions = {
        method: "POST",
        body: data
    }
    fetch('http://localhost/api/articles', fetchOptions)
        .then(response => response.json())
        .then(result => {
            console.log("result", result)
            if (result.status === "success") {
                console.log(result.message)
            } else {
                console.log(result.message)
            }
        })
        .catch(err => {
            console.error(err)
        })
}

And the backend:

@app.route('/api/articles', methods=['POST', 'PUT', 'GET'])
def handle_articles():
    try:
        if request.method == 'POST':
            logger.info("POST Request initiated\n{}".format(request.data)) # this logs "b''"
            logger.info("{}".format(request.get_json(force=True))) # This throws an error "TypeError: Object of type TypeError is not JSON serializable"
            folder = f'{ASSETS_FOLDER}/images/news'
            image_file = request.file['image']
            destination = file_upload(image_file, folder)
            if destination:
                session['upload_file_path'] = destination
                response = {"destination": destination}
            else:
                raise Exception
            return {**response, "status": "success", "message": "Successfully added article"}
        elif request.method == 'PUT':
            pass
        elif request.method == 'GET':
            pass
    except Exception as e:
        return {
            "status": "error",
            "error": e    
        }

This is what the article Object looks like from my console:

content: "<p>cont</p>"
expiration_date: null
images: Array(1)
    0: File
        path: "lake superior water color.png"
        preview: "blob:http://localhost/ecb2b28b-262c-4b43-8773-ae67290c897b"
        lastModified: 1662075561497
        lastModifiedDate: Thu Sep 01 2022 19:39:21 GMT-0400 (Eastern Daylight Time) {}
        name: "lake superior water color.png"
        size: 112822
        type: "image/png"
        webkitRelativePath: ""
        [[Prototype]]: File
length: 1
Prototype]]: Array(0)
start_date: "Sat, 10 Sep 2022 17:03:12 GMT"
title: Upload"

Side note: I’ve been able to successfully use axios to send POST requests, but I’d prefer to use the built in fetch function (I’m leaning towards just using axios)

UPDATE

I see my mistake. I got it working now with accessing the file with request.files['image'], but I am still having issues accessing the rest of the body in the request (i.e. content, title, start_date, expiration_date)

Solution

I see that the "Form" is indeed accessible in flask via request.form (🤦‍♂️)

Answered By – Kevin G

Answer Checked By – Mary Flores (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published