New-Thanasoft/thanasoft-front/PAYLOAD_CLEANING.md
2025-10-09 18:25:02 +03:00

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

  • null values 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_active becomes false
  • Payload sends: "is_active": false

When User Checks

  • form.is_active becomes true
  • 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:

  1. Better UX: Smaller payload size
  2. Clearer Intent: null explicitly means "no value"
  3. Type Safety: Ensures correct data types before sending
  4. Validation: Easier to validate before API call
  5. 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.