2

As the title says, I am trying to capture user's input through an HTML form and on submit, POST their data to an API.


I can successfully POST and get a response from the API, however none of my form data is being attached (at least I believe this is the ongoing issue).


Since this is practice I am using a free post API I found online at https://reqres.in/. All help is appreciated!

HTML

<form id="myForm">
    <label for="myName">Send me your name:</label>
    <input id="myName" name="name" value="Alex">
    <br>
    <label for="userId">your id:</label>
    <input id="userId" name="id" value="123">
    <br>
    <label for="myJob">your name:</label>
    <input id="myJob" name="job" value="Web Dev">
    <br>
    <input id="postSubmit" type="submit" value="Send Me!">
</form>

And here is my JavaScript

const thisForm = document.getElementById('myForm');
thisForm.addEventListener('submit', async function (e) {
    e.preventDefault();
    let response = await fetch('https://reqres.in/api/users', {
        method: 'POST',
        body: new FormData(thisForm)
    });

    let result = await response.json();
    alert(result.message)
    console.log(result)
});
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Jack Franklin
  • 95
  • 1
  • 2
  • 10
  • Does this answer your question? [Send POST data using XMLHttpRequest](https://stackoverflow.com/questions/9713058/send-post-data-using-xmlhttprequest) – Heretic Monkey Jan 02 '20 at 19:37

1 Answers1

6

Your form data was being appended to the POST request, but it was being appended in a format that reqres.in ignores. It seems reqres.in only processes a request body if it's a valid JSON string.

When you send a request with fetch that has a body set to new FormData(), your browser adds the Content-Type: multipart/form-data header to the request. reqres.in ignores multipart form data. The reqres.in API should respond with an error message to inform you that you've used a Content-Type that the API doesn't process correctly, rather than ignoring the body you supplied, creating a record and responding with 201 created. That's definitely a failing on their part.

Here's a working snippet using Content-Type: application/json. Beware, though, this isn't a robust way to convert a FormData object into corresponding JSON, and Object.fromEntries is only available in very modern browsers:

const thisForm = document.getElementById('myForm');
thisForm.addEventListener('submit', async function (e) {
    e.preventDefault();
    const formData = new FormData(thisForm).entries()
    const response = await fetch('https://reqres.in/api/users', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(Object.fromEntries(formData))
    });

    const result = await response.json();
    console.log(result)
});
<form id="myForm">
    <label for="myName">Send me your name:</label>
    <input id="myName" name="name" value="Alex">
    <br>
    <label for="userId">your id:</label>
    <input id="userId" name="id" value="123">
    <br>
    <label for="myJob">your name:</label>
    <input id="myJob" name="job" value="Web Dev">
    <br>
    <input id="postSubmit" type="submit" value="Send Me!">
</form>
tex
  • 2,756
  • 22
  • 31
  • 1
    I don't know why you are down voted. You are correct the form post, and the api returns a response. – Joe Swindell Jan 02 '20 at 19:46
  • 2
    Probably downvoted for my original answer, which was quite short (but included the meat of my recommendation). Unfortunately, it seems the body is still empty in the post with my current solution, so I'm still poking at a fully functional solution. – tex Jan 02 '20 at 19:58
  • 2
    Thanks for taking so much time to help me out. I have been playing around with it and I believe you are right, there is something not compatible between my data and the API. – Jack Franklin Jan 02 '20 at 21:39
  • 2
    No worries! I went ahead and added a working snippet using `Content-Type: application/json`. The code I provided is fine for testing, but probably isn't fool-proof for production. Also, it's a shame `reqres.in` responds with a `201` status to a request with a `Content-Type` equal to something other than `application/json`. I consider that a failing on their part. – tex Jan 02 '20 at 22:00