Skip to content

Commit

Permalink
Fix nested form data in Snowboard requests (#1182)
Browse files Browse the repository at this point in the history
This fix allows nested objects within the request data to be correctly converted to nested form data when sending the request.

Previously, if the data option in a Request contained nested objects or arrays within the data, these were being incorrectly converted to [Array array] or [Object object], as the FormData object would simply convert them to strings. With this fix, we traverse the data structure and ensure that they are given the right key in order to keep the shape of the data in the POST data.
  • Loading branch information
bennothommo committed Aug 14, 2024
1 parent 5cd9811 commit a03fe11
Show file tree
Hide file tree
Showing 17 changed files with 61 additions and 28 deletions.
15 changes: 8 additions & 7 deletions modules/backend/assets/ui/js/build/vendor.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion modules/system/assets/css/styles.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion modules/system/assets/js/build/manifest.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion modules/system/assets/js/build/system.debug.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion modules/system/assets/js/build/system.js

Large diffs are not rendered by default.

42 changes: 37 additions & 5 deletions modules/system/assets/js/snowboard/ajax/Request.js
Original file line number Diff line number Diff line change
Expand Up @@ -794,18 +794,50 @@ export default class Request extends PluginBase {

get data() {
const data = (typeof this.options.data === 'object') ? this.options.data : {};

const formData = new FormData(this.form || undefined);

if (Object.keys(data).length > 0) {
Object.entries(data).forEach((entry) => {
const [key, value] = entry;
formData.append(key, value);
});
this.createFormData(formData, data);
}

return formData;
}

/**
* Recursively adds data to a FormData object.
*
* This method is used internally to recursively add data to a FormData object, ensuring that
* objects and arrays are correctly prefixed and added as POST data.
*
* @param {FormData} formData
* @param {Object} data
* @param {string} prefix
* @returns {void}
*/
createFormData(formData, data, prefix = '') {
if (typeof data !== 'object') {
formData.append(prefix, data);
return;
}

if (Array.isArray(data) && prefix !== '') {
data.forEach((item) => {
this.createFormData(formData, item, `${prefix}[]`);
});
return;
}

Object.entries(data).forEach((entry) => {
const [key, value] = entry;

this.createFormData(
formData,
value,
(prefix !== '') ? `${prefix}[${key}]` : key,
);
});
}

get confirm() {
return this.options.confirm || false;
}
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion modules/system/assets/js/snowboard/build/snowboard.base.js

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a03fe11

Please sign in to comment.