1

I made a form that sends the input data to the Mailchimp audience list with their API. The issue I'm having is that my form takes two inputs, a user's firstname, and email, and upon submission of the form only the email input gets sent to Mailchimp and saved twice under email_address and firstName fields in their audience list thing. I want the email to go to the email field and the name to the firstName field. I can't see why this doesn't work per Mailchimp docs the firstName is to be prompted by a merge_fields object. However, their docs have 0 examples.

I made this subscribeUser file to handle the API request:

import fetch from "isomorphic-unfetch";

export default async (req, res) => {
  const { firstName, email } = req.body;

  console.log({ firstName });
  console.log({ email });

  if (!firstName && !email) {
    return res.status(400).json({ error: "Email and name is required" });
  }

  try {
    const AUDIENCE_ID = process.env.MAILCHIMP_AUDIENCE_ID;
    const API_KEY = process.env.MAILCHIMP_API_KEY;
    const DATACENTER = process.env.MAILCHIMP_API_SERVER;
    const data = {
      email_address: email,
      merge_fields: {
        FNAME: firstName,
      },
      status: "subscribed",
    };

    const response = await fetch(
      `https://${DATACENTER}.api.mailchimp.com/3.0/lists/${AUDIENCE_ID}/members`,

      {
        body: JSON.stringify(data),
        headers: {
          Authorization: `apikey ${API_KEY}`,
          "Content-Type": "application/json",
        },
        method: "POST",
      }
    );

    if (response.status >= 400) {
      return res.status(400).json({
        error: `There was an error subscribing to the newsletter.
        Please try again later.`,
      });
    }

    return res.status(201).json({ error: "" });
  } catch (error) {
    return res.status(500).json({ error: error.message || error.toString() });
  }
};

I made this Subscribe form to handle the input data:

import { motion } from "framer-motion";
import { useMemo, useRef } from "react";
import getScrollAnimation from "../utils/getScrollAnimation";
import ScrollAnimationWrapper from "./Layouts/ScrollAnimationWrapper";

const Subscribe = () => {
  // scroll animation

  const scrollAnimation = useMemo(() => getScrollAnimation(), []);

  const inputRef = useRef(null);

  const subscribeUser = async (e) => {
    e.preventDefault();

    // this is where the mailchimp request is made

    const res = await fetch("/api/subscribeUser", {
      body: JSON.stringify({
        firstName: inputRef.current.value,
        email: inputRef.current.value,
      }),

      headers: {
        "Content-Type": "application/json",
      },

      method: "POST",
    });
  };

  return (
    <div>
      <ScrollAnimationWrapper className="relative w-full mt-16">
        <motion.div variants={scrollAnimation} custom={{ duration: 3 }}>
          <div className="absolute rounded-xl py-8 sm:py-14 px-6 sm:px-12 lg:px-16 w-full flex flex-col sm:flex-row justify-between items-center z-10 bg-white-500">
            <div className="flex flex-col text-left w-10/12 sm:w-7/12 lg:w-5/12 mb-6 sm:mb-0">
              <h5 className="text-black-600 text-xl sm:text-2xl lg:text-3xl leading-relaxed font-medium">
                Subscribe to my newsletter
                <br />{" "}
              </h5>
              <p>I look foward to ocnnecting with you soon</p>
            </div>
            <div className="flex flex-col w-10/12 sm:w-5/12 lg:w-7/12">
              <form onSubmit={subscribeUser}>
                <div className="flex flex-row">
                  <label
                    htmlFor="name-input"
                    className="mb-3 text-sm leading-none text-gray-800"
                  >
                    First name
                  </label>
                  <input
                    type="name"
                    id="name"
                    name="name"
                    tabIndex={0}
                    ref={inputRef}
                    required
                    aria-label="Enter first name"
                    className="w-54 bg-gray-100 text-sm font-medium leading-none text-gray-800 p-3 border rounded border-gray-200"
                    defaultValue="name"
                  />
                </div>
                <div className="flex flex-row">
                  <label
                    htmlFor="email-input"
                    className="mb-3 text-sm leading-none text-gray-800"
                  >
                    Email Address
                  </label>
                  <input
                    type="email"
                    id="email"
                    name="email"
                    ref={inputRef}
                    required
                    tabIndex={0}
                    aria-label="Enter email Address"
                    className="w-54 bg-gray-100 text-sm font-medium leading-none text-gray-800 p-3 border rounded border-gray-200"
                    defaultValue="email@gmail.com"
                  />
                </div>

                <button type="submit" value="" name="subscribe">
                  Send
                </button>
              </form>
            </div>
          </div>
        </motion.div>
      </ScrollAnimationWrapper>
    </div>
  );
};

export default Subscribe;
1raf
  • 57
  • 4

1 Answers1

0

I realized my error. I was only using one useRef instance to track the two inputs. I modified it to

const Subscribe = () => {
  // scroll animation

  const scrollAnimation = useMemo(() => getScrollAnimation(), []);

  const firstNameRef = useRef(null);
  const emailRef = useRef(null);

  const subscribeUser = async (e) => {
    e.preventDefault();

    // this is where the mailchimp request is made

    const res = await fetch("/api/subscribeUser", {
      body: JSON.stringify({
        firstName: firstNameRef.current.value,
        email: emailRef.current.value,
      }),

      headers: {
        "Content-Type": "application/json",
      },

      method: "POST",
    });
  };
1raf
  • 57
  • 4