BuzzForm
BuzzFormDocs

Output Transformation

Transform nested form data to flat path-keyed objects for API submission.

Output Transformation

BuzzForm can transform nested form data into flat, path-keyed objects for APIs that expect this format.

OutputConfig

Configure output transformation in useForm:

Prop

Type

Basic Usage

Transform nested data to flat keys:

import { userProfileSchema } from "@/lib/schemas/user-profile";
import { useForm } from "@buildnbuzz/form-react";

export function ProfileForm() {
  const form = useForm({
    schema: userProfileSchema,
    output: { type: "path" }, // Flatten to dot-notation keys
    onSubmit: ({ value }) => {
      // Without output: { name: "John", address: { city: "NYC", zip: "10001" } }
      // With output:    { name: "John", "address.city": "NYC", "address.zip": "10001" }
      submitToApi(value);
    },
  });

  // ... render form
}

Custom Delimiter

Change the delimiter from . to another character:

const form = useForm({
  schema: userProfileSchema,
  output: {
    type: "path",
    delimiter: "/", // Use slash instead of dot
  },
  onSubmit: ({ value }) => {
    // { name: "John", "address/city": "NYC", "address/zip": "10001" }
    submitToApi(value);
  },
});

Utility Functions

BuzzForm exports helpers for manual transformation:

flattenToPathKeys

Convert nested object to flat path keys:

import { flattenToPathKeys } from "@buildnbuzz/form-core";

const nested = {
  name: "John",
  address: {
    city: "NYC",
    zip: "10001",
  },
};

const flat = flattenToPathKeys(nested);
// { name: "John", "address.city": "NYC", "address.zip": "10001" }

// Custom delimiter
const flatSlash = flattenToPathKeys(nested, "/");
// { name: "John", "address/city": "NYC", "address/zip": "10001" }

expandPathKeys

Convert flat path keys back to nested object:

import { expandPathKeys } from "@buildnbuzz/form-core";

const flat = {
  name: "John",
  "address.city": "NYC",
  "address.zip": "10001",
};

const nested = expandPathKeys(flat);
// { name: "John", address: { city: "NYC", zip: "10001" } }

// Custom delimiter
const nestedSlash = expandPathKeys(flat, "/");

transformFormOutput

Full transformation with config:

import { transformFormOutput } from "@buildnbuzz/form-core";

const data = {
  user: {
    name: "John",
    address: {
      city: "NYC",
    },
  },
};

// Transform to path-keyed format
const transformed = transformFormOutput(data, { type: "path" });
// { "user.name": "John", "user.address.city": "NYC" }

// With custom delimiter
const transformedSlash = transformFormOutput(data, {
  type: "path",
  delimiter: "/",
});
// { "user/name": "John", "user/address/city": "NYC" }

When to Use

Use output transformation when:

  • Your API expects flat keys like "user.address.city"
  • You're migrating from a form library that uses path-based data
  • You need to match a specific backend format

Don't use when:

  • Your API accepts standard nested JSON (most do)
  • You're using server actions with typed parameters
  • The added complexity isn't worth it

Example: API Integration

import { userProfileSchema } from "@/lib/schemas/user-profile";
import { useForm } from "@buildnbuzz/form-react";

export function ProfileForm() {
  const form = useForm({
    schema: userProfileSchema,
    output: { type: "path" },
    onSubmit: async ({ value }) => {
      // value is now flat: { name: "John", "address.city": "NYC", "address.zip": "10001" }

      await fetch("/api/profile", {
        method: "POST",
        body: JSON.stringify(value),
        headers: { "Content-Type": "application/json" },
      });
    },
  });

  // ... render form
}

Example: Job Application with Arrays

For complex schemas with arrays, output transformation flattens array indices:

import { jobApplicationSchema } from "@/lib/schemas/job-application";
import { useForm } from "@buildnbuzz/form-react";

export function ApplicationForm() {
  const form = useForm({
    schema: jobApplicationSchema,
    output: { type: "path" },
    onSubmit: ({ value }) => {
      // Transforms to:
      // {
      //   "fullName": "John Doe",
      //   "email": "john@example.com",
      //   "workHistory.0.company": "Acme Inc.",
      //   "workHistory.0.role": "Engineer",
      //   "workHistory.1.company": "Corp",
      //   "workHistory.1.role": "Senior Engineer",
      //   "skills.0.name": "React",
      //   "skills.0.level": "Advanced"
      // }
      submitToApi(value);
    },
  });

  // ... render form
}

On this page