Skip to content

Conversation

omarmciver
Copy link

Description

This PR fixes an issue with FormData handling when arrays are involved, particularly for multi-file uploads.

The Problem

When an API endpoint accepts an array of files (or any array in FormData), the current implementation incorrectly converts the entire array to a string representation instead of properly appending each item individually to the FormData object.

Example scenario:

// API expects multiple file attachments
const files = [file1, file2, file3];
api.uploadMultiple({ files });

// Current behavior: FormData contains
// "files" => "[object File],[object File],[object File]" ❌

// Expected behavior: FormData should contain
// "files" => file1
// "files" => file2  
// "files" => file3 ✅

The Solution

This fix modifies the FormData content formatter to:

  1. Detect when a property value is an array
  2. Iterate through each item in the array
  3. Properly append each item individually to FormData
  4. Preserve the correct handling of Blob/File types vs other data types

Changes Made

  • Updated templates/base/http-clients/fetch-http-client.ejs to handle arrays in FormData
  • Added test fixture formdata-arrays.json to verify the fix
  • All existing tests pass with updated snapshots

Use Cases

This fix is essential for:

  • Multi-file upload endpoints
  • Batch document processing APIs
  • Any FormData field that accepts multiple values
  • Services handling attachments (e.g., agreement management systems)

Testing

  • ✅ All existing tests pass
  • ✅ Snapshots updated to reflect the new array handling
  • ✅ Added test fixture for multi-file upload scenario

Backwards Compatibility

This change is fully backwards compatible:

  • Single values continue to work as before
  • Arrays are now handled correctly instead of being stringified
  • No breaking changes to the API

When FormData contains arrays (e.g., multiple file uploads), the current
implementation incorrectly stringifies the entire array instead of
appending each item individually.

This fix:
- Detects when a property is an array
- Iterates through each array item
- Properly appends each file/blob individually to FormData
- Preserves non-file array items by JSON.stringify-ing them individually

This enables proper multi-file uploads and array handling in FormData,
which is essential for APIs that accept multiple attachments or files.
Copy link

changeset-bot bot commented Sep 23, 2025

⚠️ No Changeset found

Latest commit: 6e854b8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR


for (const formItem of propertyContent) {
const isFileType = formItem instanceof Blob || formItem instanceof File;
formData.append(key, isFileType ? formItem : JSON.stringify(formItem));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String type values do not need to be converted to strings again, as this can result in double quotes at both ends of the string

image

Copy link

@lc-soft lc-soft Oct 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried modifying it this way and it can solve the problem.

formData.append(
  key,
  formItem instanceof Blob || typeof formItem === "string"
    ? formItem
    : JSON.stringify(formItem)
);
image

const propertyContent = property instanceof Array ? property : [property];

for (const formItem of propertyContent) {
const isFileType = formItem instanceof Blob || formItem instanceof File;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since File extends Blob, you can simplify this check to just formItem instanceof Blob.

- Remove redundant File instanceof check (File extends Blob)
- Add explicit string type check to prevent double-stringification
- Strings now passed directly to FormData instead of JSON.stringify

Thanks to @lc-soft for the code review and suggestions!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@omarmciver
Copy link
Author

@lc-soft Thank you for the excellent code review! I've implemented both of your suggestions:

  1. Simplified Blob check: Removed redundant File instanceof check since File extends Blob
  2. Fixed string handling: Added explicit string type check to prevent double-stringification

The updated code now correctly handles:

  • Blob/File types: Passed directly to FormData ✅
  • Strings: Passed directly without JSON.stringify ✅
  • Objects/Arrays: JSON.stringify applied ✅
  • Numbers/Booleans: JSON.stringify applied ✅

Most importantly: The original bug fix (handling arrays in FormData for multi-file uploads) still works perfectly! 🎉

Changes pushed in commit b9da1cd

Update test snapshots to reflect the simplified FormData handling:
- Removed redundant File instanceof check
- Added string type check to prevent double-stringification

All 133 tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@omarmciver
Copy link
Author

Tests fixed!

Updated all test snapshots to reflect the refactored FormData handling. All 133 tests now passing.

Changes in commit 6e854b8:

  • 28 snapshot files updated
  • 114 snapshots refreshed
  • All tests green ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants