I've searched around a lot for an answer on this topic, and even though there's lots of questions surrounding this issue I'm yet to have found a solution that works for me.
The problem I'm having is that WP Ajax can't find an action, it fails at the following check:
if ( empty( $_REQUEST['action'] ) ) {
wp_die( '0', 400 );
}
If I remove all checks for the action and hard code the action WordPress can find it, so that's not the issue, the issue is in the AJAX call. During the hard coded test if I return either $_POST
or $_REQUEST
is see returned an empty array
Here's the function that gets called on form submit:
document.getElementById('contact-form').addEventListener('submit', (e) => {
e.preventDefault();
// Store all the field names needing to have their values retrieved
const fieldGroups = [
'action',
'name',
'email',
'subject',
'message',
];
// Set an object which gets filled with the forms data. 'fieldName': 'fieldValue'
const formData: any = {
};
fieldGroups.forEach((field) => {
// Get the input element
const input: HTMLFormElement = document.querySelector(`[name=${field}]`);
// Check it's valid
const isValid = input.checkValidity();
// Grab the value
const value = input.value;
// If the field is valid and has content add it to the formData object
if (isValid && value.length > 0) {
formData[field] = value;
}
});
// Call the postData function passing the wp_ajax url and formData
// Console logging shows the ajax url is correct
postData(wp_ajax.ajaxurl, formData)
.then((data) => console.log(JSON.stringify(data)))
.catch(() => console.log(formData));
function postData(url: string, data: object) {
return fetch(url, {
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
})
.then((response) => response.json());
}
});
The params as recieved by the POST request:
JSON
action: jh_form
email: [email protected]
message: Test Message
name: Test Name
subject: Test subject
Request Payload
{"action":"jh_form","name":"Test Name","email":"[email protected]","subject":"Test subject","message":"Test Message"}
So the action is certainly there, I don't understand why WordPress can't find it, I've done this countless times using jQuery so is this an error in the way I'm using Fetch? Are the headers incorrect (I have tested this with the header application/x-www-form-urlencoded
too with no luck)?