ncox85 ncox85 - 1 year ago 233
Ajax Question

Email submit through Mailchimp returning error, Javascript and php

I am hoping this is a simple issue. I am using the Mailchimp API to submit a simple email signup form from my website. I am trying to learn javascript right now, so I am trying to do the httprequest and callback without jQuery. Basically, I am trying to convert this jQuery sample I found online to vanilla Javascript. But there is something (several things?) wrong with my javascript that I don't understand.

EDIT: When the form is submitted, I am taken to the email-validate.php page, and show the following error object returned by MailChimp.

{"type":"","title":"Invalid Resource","status":400,"detail":"The resource submitted could not be validated. For field-specific details, see the 'errors' array.","instance":"","errors":[{"field":"","message":"Required fields were not provided: email_address"},{"field":"email_address","message":"Schema describes string, NULL found instead"}]}


Found here (this actually throws an ajax(...).success is not a function error in the console but still submits the form, FWIW)


//prevent the form from submitting via the browser redirect

//grab attributes and values out of the form
var data = {email: $('#mc-email').val()};
var endpoint = $(this).attr('action');

//make the ajax request
method: 'POST',
dataType: "json",
url: endpoint,
data: data
//successful adds will have an id attribute on the object
alert('thanks for signing up');
} else if (data.title == 'Member Exists') {
//MC wil send back an error object with "Member Exists" as the title
alert('thanks, but you are alredy signed up');
} else {
//something went wrong with the API call
alert('oh no, there has been a problem');
//the AJAX function returned a non-200, probably a server problem
alert('oh no, there has been a problem');

My Javascript (that doesn't work)

document.addEventListener("DOMContentLoaded", function() {
document.getElementById("mc-form", function submit(e){

var data = {"email": document.getElementById("mc-email").value};
var endpoint = document.getElementById("mc-form").getAttribute('action');

function formSubmit(callback){
var request = new XMLHttpRequest();

request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200) {
//Parse returned string into an object, then pass the object to the callback function.
var response = JSON.parse(request.responseText);
} else {
console.log('JSON request error');
}"POST", endpoint , true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
function formResponse(response){
//successful adds will have an id attribute on the object
alert('Thank you for signing up for Launch Alerts!');
} else if (response.title == 'Member Exists') {
//MC wil send back an error object with "Member Exists" as the title
alert('You are already signed up for Launch Alerts!');
} else {
//something went wrong with the API call
alert('Something went wrong. Please resubmit the form!');

My html

<form class="mc-form" method="POST" action="./email-validate.php">
<h2 class="launch-alerts">Never miss a launch with Launch Alerts</h2>
<label for="mc-email">Email Address:</label>
<input type="email" id="mc-email" name="mc-email" autofocus="true" required/>
<input type="text" value="pending" id="status" name="status" hidden/>
<input type="submit" value="Submit">

It uses a php file to validate and submit the form, as can be seen on the link above. The html and php work to submit the form when using the jQuery script, but not my javascript, which means there is something wrong with my script, but I am too new with javascript to fully understand what it is I am trying to do, and what I am doing wrong.



The PHP code (copied directly from here

//fill in these values for with your own information
$api_key = 'xxxxxxxxxxxxxxxxxxxxxxxx';
$datacenter = 'xxxxx';
$list_id = 'xxxxxxxxx';
$email = $_POST['email'];
$status = 'pending';
$status = $_POST['status'];
$url = 'https://'.$datacenter.''.$list_id.'/members/';
$username = 'apikey';
$password = $api_key;
$data = array("email_address" => $email,"status" => $status);
$data_string = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$api_key");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
$result=curl_exec ($ch);
curl_close ($ch);
echo $result;

Answer Source

The data argument to request.send() must be a URL-encoded string, you're passing an object. jQuery does this conversion automatically for you; when you do it yourself, you have to do that yourself as well.

var data = "email=" + encodeURIComponent(document.getElementById("mc-email").value);

You're also not adding your submission function to the form's submit event correctly. It should be:

document.getElementById("mc-form").addEventListener("submit", function submit(e){