FAQ
Frequently Asked Questions
How do I capture error/success responses in JavaScript?
Learn how to handle form submission responses programmatically
Formserve returns JSON responses for all form submissions, making it easy to capture and handle success/error states in your JavaScript code.
API Response Format
Success Response (HTTP 200):
{
"status": "success",
"message": "Form submitted successfully",
"redirect_url": "https://example.com/thank-you"
}
Error Response (HTTP 422):
{
"status": "error",
"message": "Failed to save submission",
"errors": ["Field name is required", "Email is invalid"]
}
Method 1: Using Modern Fetch API (Recommended)
document.getElementById('myForm').addEventListener('submit', async function(e) {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
const submitButton = form.querySelector('button[type="submit"]');
// Show loading state
submitButton.disabled = true;
submitButton.textContent = 'Submitting...';
try {
const response = await fetch(form.action, {
method: 'POST',
body: formData
});
const data = await response.json();
if (response.ok && data.status === 'success') {
// Handle success
console.log('Success:', data);
// Show success message
document.getElementById('success-message').textContent = data.message;
document.getElementById('success-message').classList.remove('hidden');
// Optionally redirect
if (data.redirect_url) {
window.location.href = data.redirect_url;
} else {
form.reset(); // Clear the form
}
} else {
// Handle error
console.error('Error:', data);
// Show error message
const errorDiv = document.getElementById('error-message');
errorDiv.textContent = data.message;
// Show specific field errors if available
if (data.errors && data.errors.length > 0) {
errorDiv.innerHTML = `
<p>${data.message}</p>
<ul>
${data.errors.map(err => `<li>${err}</li>`).join('')}
</ul>
`;
}
errorDiv.classList.remove('hidden');
}
} catch (error) {
// Handle network errors
console.error('Network error:', error);
document.getElementById('error-message').textContent =
'An error occurred. Please try again.';
document.getElementById('error-message').classList.remove('hidden');
} finally {
// Reset button state
submitButton.disabled = false;
submitButton.textContent = 'Submit';
}
});
Method 2: Using XMLHttpRequest
document.getElementById('myForm').addEventListener('submit', function(e) {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
const xhr = new XMLHttpRequest();
xhr.open('POST', form.action);
xhr.onload = function() {
const data = JSON.parse(xhr.responseText);
if (xhr.status === 200 && data.status === 'success') {
// Success
console.log('Success:', data);
alert(data.message);
if (data.redirect_url) {
window.location.href = data.redirect_url;
}
} else {
// Error
console.error('Error:', data);
alert(data.message);
if (data.errors) {
console.error('Validation errors:', data.errors);
}
}
};
xhr.onerror = function() {
alert('Network error occurred');
};
xhr.send(formData);
});
Method 3: With React
import { useState } from 'react';
function ContactForm() {
const [status, setStatus] = useState('idle'); // idle, loading, success, error
const [message, setMessage] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
setStatus('loading');
const formData = new FormData(e.target);
try {
const response = await fetch('https://formserve.io/f/YOUR_ENDPOINT_KEY', {
method: 'POST',
body: formData
});
const data = await response.json();
if (response.ok && data.status === 'success') {
setStatus('success');
setMessage(data.message);
e.target.reset();
if (data.redirect_url) {
setTimeout(() => window.location.href = data.redirect_url, 2000);
}
} else {
setStatus('error');
setMessage(data.errors?.join(', ') || data.message);
}
} catch (error) {
setStatus('error');
setMessage('An error occurred. Please try again.');
}
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
{status === 'success' && (
<div className="success">{message}</div>
)}
{status === 'error' && (
<div className="error">{message}</div>
)}
<button type="submit" disabled={status === 'loading'}>
{status === 'loading' ? 'Submitting...' : 'Submit'}
</button>
</form>
);
}
Complete HTML + JavaScript Example
<!DOCTYPE html>
<html>
<head>
<style>
.hidden { display: none; }
.success { color: green; padding: 10px; background: #d4edda; }
.error { color: red; padding: 10px; background: #f8d7da; }
</style>
</head>
<body>
<form id="contactForm" action="https://formserve.io/f/YOUR_ENDPOINT_KEY" method="POST">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea>
</div>
<button type="submit" id="submitBtn">Send Message</button>
</form>
<div id="successMessage" class="success hidden"></div>
<div id="errorMessage" class="error hidden"></div>
<script>
const form = document.getElementById('contactForm');
const submitBtn = document.getElementById('submitBtn');
const successMsg = document.getElementById('successMessage');
const errorMsg = document.getElementById('errorMessage');
form.addEventListener('submit', async function(e) {
e.preventDefault();
// Hide previous messages
successMsg.classList.add('hidden');
errorMsg.classList.add('hidden');
// Show loading state
submitBtn.disabled = true;
submitBtn.textContent = 'Sending...';
try {
const response = await fetch(form.action, {
method: 'POST',
body: new FormData(form)
});
const data = await response.json();
if (response.ok && data.status === 'success') {
// Success
successMsg.textContent = data.message || 'Thank you! Your message has been sent.';
successMsg.classList.remove('hidden');
form.reset();
// Optional redirect
if (data.redirect_url) {
setTimeout(() => {
window.location.href = data.redirect_url;
}, 2000);
}
} else {
// Error
let errorText = data.message || 'Something went wrong';
if (data.errors && data.errors.length > 0) {
errorText += ': ' + data.errors.join(', ');
}
errorMsg.textContent = errorText;
errorMsg.classList.remove('hidden');
}
} catch (error) {
errorMsg.textContent = 'Network error. Please check your connection and try again.';
errorMsg.classList.remove('hidden');
} finally {
submitBtn.disabled = false;
submitBtn.textContent = 'Send Message';
}
});
</script>
</body>
</html>
Key Points:
- Always prevent default form submission with
e.preventDefault()to handle the response in JavaScript - Check both HTTP status (
response.okorxhr.status === 200) and the status field in the JSON response - The redirect_url field is optional - only present if you configured a redirect URL in your endpoint settings
- Error responses may include an
errorsarray with specific validation messages - Handle network errors separately from API errors in the catch block
HTTP Status Codes
200 OK- Submission successful422 Unprocessable Entity- Validation error or submission failed404 Not Found- Invalid endpoint key429 Too Many Requests- Rate limit exceeded (with high spam protection)
More Questions Coming Soon
We're continuously adding more frequently asked questions. If you have a question that's not covered here, please contact support.