data_object-to-form-data.js

/**
 * @module objectToFormData
 * @description Creates a FormData object and populate it with data from the the provided object.
 *
 * @since 1.0.0
 *
 * @param {object} obj        The source of data to be used when populating FormData.
 * @param {string} rootName   The root name of the field for each data value.
 * @param {Array}  ignoreList Array of property names to be ignored when populating FormData.
 *
 * @return {FormData} Returns a FormData object, populated with data from the provided object.
 *
 * @example
 * import { objectToFormData } from "@gravityforms/utils";
 *
 * function Example() {
 * 	const obj = {
 * 		one: 1,
 * 		two: 2,
 * 		three: {
 * 			a: 'a',
 * 			b: 'b',
 * 		},
 * 	};
 *
 * 	const output = objectToFormData( obj, 'data', [ 'data[one]' ] );
 * }
 *
 */
const objectToFormData = ( obj, rootName, ignoreList ) => {
	const formData = new window.FormData();

	function appendFormData( data, root ) { // eslint-disable-line jsdoc/require-jsdoc
		if ( ! ignore( root ) ) {
			root = root || '';
			if ( data instanceof window.File ) {
				formData.append( root, data );
			} else if ( Array.isArray( data ) ) {
				for ( let i = 0; i < data.length; i++ ) {
					appendFormData( data[ i ], root + '[' + i + ']' );
				}
			} else if ( typeof data === 'object' && data ) {
				for ( const key in data ) {
					if ( Object.prototype.hasOwnProperty.call( data, key ) ) {
						if ( root === '' ) {
							appendFormData( data[ key ], key );
						} else {
							appendFormData(
								data[ key ],
								root + '[' + key + ']'
							);
						}
					}
				}
			} else if ( data !== null && typeof data !== 'undefined' ) {
				formData.append( root, data );
			}
		}
	}

	function ignore( root ) { // eslint-disable-line jsdoc/require-jsdoc
		return (
			Array.isArray( ignoreList ) &&
			ignoreList.some( ( x ) => x === root )
		);
	}

	appendFormData( obj, rootName );

	return formData;
};

export default objectToFormData;