0

I managed to configure everything as expected with Formik, and the AJAX requests seems fine (it shows me the success message if I enable it), but the Netlify form section is still empty (even if the form is listed and acknowledged by Netlify).

This is my contact component:

(I think the problem is on my ajax code under the onSubmit function)

import React from 'react'
import { Formik, Form, Field, ErrorMessage } from 'formik'
import Layout from "../components/layout"
import SEO from "../components/seo"


const ContactForm = () => (
<Layout>
    <SEO title="Form with Formik" />
    <main class="page-contact-form">
    <h1>Do your booking</h1>
    <Formik
        initialValues={{ email: '', name: '', start: '', end: '', message: '' }}
        validate={values => {
            let errors = {};
            if (!values.email) {
                errors.email = 'Required';
            } else if (
                !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
            ) {
                errors.email = 'Invalid email address';
            }
            return errors;
        }}

    onSubmit={(values) => {
        fetch("/", {
            method: "POST",
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            body: ({
                "form-name": "contact",
                ...values
            })
        }).then(() => alert("Thank you!"))

        }}
    >
        {({ isSubmitting }) => (
        <Form name="contact" data-netlify="true" action="/grazie">
                <input type="hidden" name="form-name" value="contact" />
            <label>Name and Surname: <br />
                    <Field type="text" name="name" placeholder="Nome Cognome" />
                    <ErrorMessage name="name" component="div" />
            </label>
            <br />
            <label>Email: <br />
            <Field type="email" name="email" placeholder="Richiesto" />
            <ErrorMessage name="email" component="div" />
            </label>
            <br />

            <label>Start and End <br />

            <Field type="date" name="start" />
            <ErrorMessage name="start" />
            &nbsp;
            <Field type="date" name="end" />
            <ErrorMessage name="end" />
            </label>
                <br />
            <label>
                Message: <br />
                <Field type="text" name="message" />
                <ErrorMessage name="message" />
            </label>
            <br />
            <button type="submit" disabled={isSubmitting}>
                Submit
            </button>
        </Form>
        )}
    </Formik>
    </main>
</Layout>
)

export default ContactForm
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Santiago
  • 361
  • 4
  • 21

1 Answers1

2

In the fetch function in onsubmit, it looks like you're sending an object, but the content type is url encoded? Perhaps you need to serialize your object into url encoded format first. There's a host of solutions for that in this question. If you go with the top suggestion:

// https://stackoverflow.com/a/1714899/10340970
const serialize = function(obj) {
  var str = [];
  for (var p in obj)
    if (obj.hasOwnProperty(p)) {
      str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
    }
  return str.join("&");
}


...
fetch("/", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: serialize({
    "form-name": "contact",
    ...values
  })
Derek Nguyen
  • 11,294
  • 1
  • 40
  • 64
  • Thanks, I'll try. I fully don't understand why I need to "serialize" but now it's start to become clear why on another example there was an "encode" function: this one seems to work https://github.com/imorente/gatsby-netlify-form-example/blob/master/src/pages/contact.js as you can see there is an "encode" function that apparently does this serialize thing (sorry I don't fully understand Javascript). The fact is that I wanted to try "Formik component" so I tried to applied the same logic on my component. – Santiago Apr 15 '19 at 08:27
  • 1
    @Santiago ah yep, that function is doing a similar thing as the serialize function I linked above. The reason why is that netlify form API might only accept url-encoded string, which looks like this: `field=value&field2...` Meanwhile, you're sending over an object over fetch, which netlify probably can't read (nor any other api for that matter, you'd always have to serialize it one way or another. Some ajax library does this for you, but `fetch` does not — for example, if you want to send over `content-type: application/json`, you'd have to set body as `body: JSON.stringify(content)`). – Derek Nguyen Apr 15 '19 at 08:46
  • Ok I made a few tries and with the function encode (placed as a function outside the main component) it works! The serialize function does not work but maybe I should change it like the encode one, I mean something like: function serialize(obj) ... etc etc... ? Thanks for clarify things out! – Santiago Apr 15 '19 at 08:59
  • @Santiago ah hahah I copied the function over but forgot to add the word `const` at the beginning of the code block, will edit. That encode function does the same thing, so I'm sure you're safe (your object have to be 'shallow' though i.e no nested object). Glad you got it solved. – Derek Nguyen Apr 15 '19 at 09:08
  • Oh that was it! Is it the same if instead of const serialize I do: function serialize(data) {...} ? PS: what do you mean with shallow / nested? – Santiago Apr 15 '19 at 09:11
  • 1
    @Santiago check out the second `console.log` in the [original example](https://stackoverflow.com/a/1714899/10340970), it accounts for nested objects. Shallow object is like this: `{ one: 'two' }`, nested object is like this: `{ one: { two: 'three'} }` – Derek Nguyen Apr 15 '19 at 09:15
  • thanks for the explanation. Just facing this exact problem right now. I add a field that gives me nested object (date of start and date of end), and the form request of netlify doesn't get it. I'll try with serialize, do it work for nested or is like the encode function? – Santiago Apr 18 '19 at 08:42
  • I opened a new question in case you're interested: https://stackoverflow.com/questions/55748153/is-netlify-able-to-receive-nested-values-on-forms-feature-react-dates-with-for – Santiago Apr 18 '19 at 14:31