Search code examples
javascriptnode.jsreactjsreact-hooksnodemailer

Updated: why is my buttonText not changing it's status even the onClick executes the function task?


My main goal is to have a contact form made of node.js and reactjs material ui. this project is a dummy which i will integrate to the main one.

this is my first work with node.js. using nodemailer i have created a index.js file for sending email. the code is given below:

const express = require("express");
const router = express.Router();
const cors = require("cors");
const nodemailer = require("nodemailer");

const app = express();
app.use(cors());
app.use(express.json());
app.use("/", router);
app.listen(5000, () => console.log("Server Running"));

const contactEmail = nodemailer.createTransport({
  service: "gmail",
  auth: {
    user: "*******@gmail.com",
    pass: "********",
  },
});

contactEmail.verify((error) => {
  if (error) {
    console.log(error);
  } else {
    console.log("Ready to Send");
  }
});

router.post("/contact", (req, res)  =>{
  const name = req.body.name;
  const email = req.body.email;
  const message = req.body.message;
  const mail = {
    from: name,
    to: "random_emil@gmail.com",
    subject: "Contact Form Message",
    html: `<p>Name: ${name}</p><p>Email: ${email}</p><p>Message: ${message}</p>`,
  };
contactEmail.sendMail(mail, (error)=>  {
  if(error){
  res.JSON.stringify(error);
  }else{
    res.JSON.stringify({ 'result': " email sent successfully" });
  }
})

})

while executing node server it shows no error.

in client side, i have written the Contact.js with material-ui:

import React,{useState} from 'react'
import axios from 'axios'
import { Button,FormControl, TextField } from "@material-ui/core";
export default function Contact() {
    const [data, setData] = useState({
      name: "",
      email: "",
      message: "",
      sent: false,
      buttonText: "Submit",
      err: "",
    });

    const handleChange = (e) => {
      const { name, value } = e.target;
      setData({
        ...data,
        [name]: value,
      });
    };
    const formSubmit = (e) => {
        e.preventDefault();

        setData({
            ...data,
            buttonText: 'Sending...'
        })

        axios
          .post("http://localhost:5000/contact", data)
          .then((res) => {
            if (res.data.result !== "email sent successfully") {
              setData({
                ...data,
                buttonText: "Failed to send",
                sent: false,
                err: "fail",
              });
              setTimeout(() => {
                resetForm();
              }, 3000);
            } else {
              setData({
                ...data,
                sent: true,
                buttonText: "Sent",
                err: "success",
              });
              setTimeout(() => {
                resetForm();
              }, 3000);
            }
          })
          .catch((err) => {
            //console.log(err.response.status)
            setData({
              ...data,
              buttonText: "Failed to send",
              err: "fail",
            });
          });
          const resetForm = () => {
            setData({
              name: "",
              email: "",
              message: "",
              sent: false,
              buttonText: "Submit",
              err: "",
            });
          };
    }
    return (
      <React.Fragment>
        <FormControl fullWidth={true}>
          <TextField
            required
            label="Full name"
            variant="filled"
            id="full-name"
            name="name"
            className="form-field"
            value={data.name}
            onChange={handleChange}
          />
        </FormControl>
        <FormControl fullWidth={true}>
          <TextField
            required
            label="Email"
            id="email"
            name="email"
            variant="filled"
            className="form-field"
            value={data.email}
            onChange={handleChange}
          />
        </FormControl>
        
        <FormControl fullWidth={true}>
          <TextField
            required
            label="Message"
            variant="filled"
            name="message"
            multiline={true}
            rows="10"
            value={data.message}
            onChange={handleChange}
          />
        </FormControl>
        <FormControl>
          <div className="form-submit">
            <Button variant="contained" color="primary" onClick={formSubmit}>
              {data.buttonText}
            </Button>
          </div>
        </FormControl>
      </React.Fragment>
    );
}

after executing npm start, the local server shpws the form and when i put the data in name, email and message field to submit the Button shows sending..... and it never ends. but in my email i found the email delivered by the server js exactly what i anted.

how can i update my {buttonText} message into submit? what did i do wrong in formSubmit function?

please help


Solution

  • Your server code succesfully calls the .sendMail() method, which is why the email gets delivered. However, your response code is incorrect. The correct Express response method for responding with a JSON payload is res.json(payload), not res.JSON.stringify(payload).

    If you fix that, it should work.