bobweirsmoustache
bobweirsmoustache

Reputation: 161

New FormData returns empty object

I am trying to use FormData to send user-entered data in a POST request with the fetch API. The problem is that when I create a new FormData object with the form that I've created, it keeps creating an empty object - no entries/keys/values. I'm not sure why since getting the form element returns the form correctly, it is when I call new FormData(form) that I get an empty form object. From the MDN documentation, it seems that the form should be fine to set up in separate divs which my form does. Does the form data that I'm providing need to be referenced by anything other than the input ids? Can anyone suggest how I can properly create the FormData object?

Thanks!

/*
* Add event listener on form submission
*/
document.addEventListener('DOMContentLoaded', () => {
    let form = document.getElementById('calc_form');
    form.addEventListener('submit', callServer);
});

/*
* Handler for form submission. Prevents the default action and calls longop() 2 times
*/
function callServer(event) {
    event.preventDefault();
    
    var form = event.currentTarget;
    console.log(form);                //prints the html element of calc_form, the form with the event listener
    var formData = new FormData(form);
    console.log(formData);            //prints empty FormData object
    var url = form.action;
    console.log('Sending calculation request to server');

    getData(url, formData)
        .then(data => addData(data))
        .catch(error => console.error(error));
}

HTML for form

<form id="calc_form" method="POST" action="/calculate">
        <div>
            <label for="first">First Value</label>
            <input type="number" id="first" name="first">
            <br>
            <label for="second">Second Value</label>
            <input type="number" id = "second" name="second">
        </div>
        <div>
            <input type="radio" id="add" name="operator" value="add">
            <label for="add">Add</label>
            <input type="radio" id="subtract" name="operator" value="subtract">
            <label for="subtract">Subtract</label>
            <input type="radio" id="multiply" name="operator" value="multiply">
            <label for="multiply">Multiply</label>
            <input type="radio" id="divide" name="operator" value="divide">
            <label for="divide">Divide</label>
        </div>
        <div>
            <button type="submit">Submit</button>
        </div>
        <div>
            <p id="results"></p>
        </div>
</form>

Upvotes: 7

Views: 8074

Answers (4)

Shtole
Shtole

Reputation: 354

Check whether you form is disabled.

I placed all inputs into a <fieldset> (to control the whole form), and disabled it before reading form data (to prevent changing values). It seems when a form is disabled, new FormData(form) is empty.

Upvotes: 0

resti
resti

Reputation: 45

For some who may face some related issue, just make sure your input elements have attribute name. below is my example.

export default function(){

const objectContext={};

const saveObject=()=>{
    let formElement = document.querySelector('#objectInfo')
    let formData = new FormData(formElement)
    for(let [key, value] of  formData.entries()){
        objectContext[key]=value
    }
    console.log(objectContext)
}
return div({style:'padding:1em;'},
        form({style:'display:flex;flex-direction:column;text-align:left',id:'objectInfo'},
            input({value:'',name:'objectName', placeholder:'Object Name'}),
            textarea({value:'',name:'objectDescription',placeholder:'Object Description'}),
            ),
        div({id:'object-context-wrapper'}),
        button({onclick:(e)=>{
            loadPage('/forms/newContext.js','#object-context-wrapper');
            e.target.disabled=true
            }},'Add Context'),
        button({onclick:()=>saveObject()},'Save Object')
    )}

The above will print the object into the console like so.

{objectName: 'Name of Object', objectDescription: 'Description Of Object'}

Upvotes: 2

Brooke Hart
Brooke Hart

Reputation: 4049

FormData is a bit unusual in this respect. When you print it to the console, you will see FormData {} but that doesn't mean it's empty. Try iterating through it using a for...of loop and you'll see it has content. You may find this page on MDN more useful: https://developer.mozilla.org/en-US/docs/Web/API/FormData

Upvotes: 6

bobweirsmoustache
bobweirsmoustache

Reputation: 161

I found the problem, there were actually 2.

The first was that on the client side code above I was trying to print the FormData object. I didn't believe that it would actually print an empty object, figured that there must be something in the entries or keys that from my input fields. After changing the console.log(form) to

    for (var [key, value] of formData.entries()) { 
        console.log(key, value);
    }

As suggested by Mark, I was able to see that the formData was actually being created properly.

The other problem was that I forgot to include app.use(bodyParser.json()) in the server side. Without this, the server was unable to parse the JSON-formatted request body. Now I get the formData contents as expected.

These two problems together was leading me to believe that I was having a problem with new FormData() but turns out I was just mishandling the data.

Upvotes: 8

Related Questions