Search code examples
javascriptreactjsasync-awaitruntime-errorreact-bootstrap

Runtime Errors When Submitting Form, Even Though Form Submission Goes Through


I have a Contact sheet on a Portfolio using React-Bootstrap for styling (hence the Form, Form.Group, etc.) and the code works (when I submit, the FormData is successfully sent through web3forms and I receive an email) but the full screen is lighting up with an "Uncaught Runtime Errors" message with the following Error: "Cannot access 'response' before initialization".

The function is being used async, and the information does go through, but I would like to fix this so that the error is removed. Any suggestions would be appreciated! Here's the code for the Contact.js file:

import React from "react";
import "./Contact.css";

import Container from "react-bootstrap/Container";
import Button from "react-bootstrap/Button";
import Form from "react-bootstrap/Form";

function ContactForm() {
    const [result, setResult] = React.useState("");

    const onSubmit = async (event) => {
        event.preventDefault();
        setResult("Contacting...");
        const formData = new FormData(event.target);

        formData.append("access_key", "****************");

        const response = await fetch("https://api.web3forms.com/submit", {
            method: "POST",
            body: formData,
        }).then((response = response.json()));

        if (response.success) {
            console.log("Success", response);
            setResult(response.message);
        } else {
            console.log("Error", response);
            setResult(response.message);
        }
    };

    return (
        <>
            <Container>
                <div className="contact-page">
                    <h4 className="contact-welcome">
                        Feel free to reach out using the following form!
                    </h4>
                </div>
                <Form onSubmit={onSubmit}>
                    <Form.Group className="mb-3" controlId="formBasicEmail">
                        <Form.Label>Email address</Form.Label>
                        <Form.Control name="email" type="email" placeholder="Enter email" required />
                        <Form.Text className="text-muted">
                            I will never share your email with anyone else!
                        </Form.Text>
                    </Form.Group>
                    <Form.Group className="mb-3" controlId="formBasicMessage">
                        <Form.Label>Message</Form.Label>
                        <Form.Control name="message" type="message" placeholder="Enter your message" required />
                        <Form.Text className="text-muted">
                            Please let me know your name and what company you're reaching out
                            on behalf of!
                        </Form.Text>
                    </Form.Group>
                    <Form.Group className="mb-3" controlId="formBasicCheckbox">
                        <Form.Check type="checkbox" label="Confirm" />
                    </Form.Group>
                    <Button variant="primary" type="submit">
                        Submit
                    </Button>
                </Form>
                <span className="contact-message">{result}</span>
            </Container>
        </>
    );
}

export default ContactForm;

Worth noting that although the form goes through the page only ever switches to "Contacting" and never updates for either a "Success" or "Error" message, in either the console or the contact-message span.

I tried changing the const response into a variable/let instead and that didn't make any difference. No matter what I have changed so far I'm still getting a eslint warning in the terminal saying 'response' was used before it was defined and on submission of the form I still get the error.

Thanks!


Solution

  • You have a typo in your code where you assign the response variable twice. You have const response = await fetch(...).then((response = response.json())), which is incorrect. You should use

    const response = await fetch(...);
    const data = await response.json();
    

    which uses two await statements to get the data.