5.7 KiB
5.7 KiB
Payload Cleaning - Form Data Transformation
Problem
The form was sending empty strings ("") instead of null for empty fields, and checkbox was sending 0 instead of true/false.
Solution
Added data cleaning logic before submitting the form.
Changes Made
1. Clean Empty Strings to Null
Before:
{
"name": "",
"email": "",
"phone": "",
"vat_number": ""
}
After:
{
"name": null,
"email": null,
"phone": null,
"vat_number": null
}
2. Ensure Boolean for is_active
Before:
{
"is_active": 0 // or "" or undefined
}
After:
{
"is_active": true // or false
}
3. Remove Empty Type Field
The type field is not used by the backend, so we remove it if empty.
Implementation
const submitForm = async () => {
// Clear errors before submitting
fieldErrors.value = {};
errors.value = [];
// Clean up form data: convert empty strings to null
const cleanedForm = {};
for (const [key, value] of Object.entries(form)) {
if (value === '' || value === null || value === undefined) {
cleanedForm[key] = null;
} else {
cleanedForm[key] = value;
}
}
// Ensure is_active is boolean
cleanedForm.is_active = Boolean(form.is_active);
// Remove type field if it's empty (not needed for backend)
if (!cleanedForm.type) {
delete cleanedForm.type;
}
// Emit the cleaned form data to parent
emit("createClient", cleanedForm);
};
Example Payloads
Empty Form (Only Required Fields)
Before cleaning:
{
"client_category_id": null,
"type": "",
"name": "",
"vat_number": "",
"siret": "",
"email": "",
"phone": "",
"billing_address_line1": "",
"billing_address_line2": "",
"billing_postal_code": "",
"billing_city": "",
"billing_country_code": "",
"group_id": null,
"notes": "",
"is_active": 0,
"default_tva_rate_id": null
}
After cleaning:
{
"client_category_id": null,
"name": null,
"vat_number": null,
"siret": null,
"email": null,
"phone": null,
"billing_address_line1": null,
"billing_address_line2": null,
"billing_postal_code": null,
"billing_city": null,
"billing_country_code": null,
"group_id": null,
"notes": null,
"is_active": true,
"default_tva_rate_id": null
}
Filled Form
Before cleaning:
{
"client_category_id": 4,
"type": "",
"name": "SARL TechnoPlus",
"vat_number": "FR98765432109",
"siret": "98765432100019",
"email": "compta@technoplus.fr",
"phone": "+33198765432",
"billing_address_line1": "789 Boulevard Haussmann",
"billing_address_line2": "",
"billing_postal_code": "75009",
"billing_city": "Paris",
"billing_country_code": "FR",
"group_id": null,
"notes": "Nouveau client entreprise",
"is_active": 1,
"default_tva_rate_id": null
}
After cleaning:
{
"client_category_id": 4,
"name": "SARL TechnoPlus",
"vat_number": "FR98765432109",
"siret": "98765432100019",
"email": "compta@technoplus.fr",
"phone": "+33198765432",
"billing_address_line1": "789 Boulevard Haussmann",
"billing_address_line2": null,
"billing_postal_code": "75009",
"billing_city": "Paris",
"billing_country_code": "FR",
"group_id": null,
"notes": "Nouveau client entreprise",
"is_active": true,
"default_tva_rate_id": null
}
Benefits
1. Cleaner Database
nullvalues instead of empty strings- Easier to query for "no value" vs "empty string"
2. Laravel Validation Works Better
Laravel handles null better than "" for:
- Optional fields
- Email validation (null is ok, "" might fail)
- Exists validation (null is ok, "" will try to find empty key)
3. Boolean Logic Works Correctly
// In Laravel
if ($request->is_active) {
// This now works correctly
}
4. Consistent Data Types
- Strings stay strings
- Nulls stay nulls
- Booleans stay booleans
- Numbers stay numbers
Checkbox Behavior
Initial State
<input
type="checkbox"
v-model="form.is_active"
:checked="form.is_active"
/>
const form = reactive({
is_active: true, // ✅ Starts checked
});
When User Unchecks
form.is_activebecomesfalse- Payload sends:
"is_active": false
When User Checks
form.is_activebecomestrue- Payload sends:
"is_active": true
Testing
Test 1: Submit Empty Form
Expected validation error:
{
"errors": {
"name": ["Le nom du client est obligatoire."]
}
}
Test 2: Submit with Only Name
Payload sent:
{
"client_category_id": null,
"name": "Test Client",
"vat_number": null,
"siret": null,
"email": null,
"phone": null,
"billing_address_line1": null,
"billing_address_line2": null,
"billing_postal_code": null,
"billing_city": null,
"billing_country_code": null,
"group_id": null,
"notes": null,
"is_active": true,
"default_tva_rate_id": null
}
Backend should accept this and create client with only name and is_active set.
Test 3: Submit with Inactive Client
Uncheck "Client actif" checkbox, then submit.
Payload sent:
{
"name": "Inactive Client",
"is_active": false,
// ... other fields
}
Why Not Clean on Backend?
We clean on frontend because:
- Better UX: Smaller payload size
- Clearer Intent:
nullexplicitly means "no value" - Type Safety: Ensures correct data types before sending
- Validation: Easier to validate before API call
- Debugging: Easier to see what data is being sent
Laravel Backend Handles Both
The Laravel backend will accept:
"field": null✅"field": ""✅ (but converts to null for nullable fields)"field": "value"✅
But we send null for consistency and clarity.