Search code examples
javascriptreactjsmultipartform-data

FormData append deep nested object


Is it possible to append nested object to FormData?

let formData = new FormData();
let data = {
    title: 'title',
    text: 'text',
    preview: {
      p_title:'p title', 
      p_text: 'p text',
      files: [
        {file: File},
        {file: File}
      ]
    }
};

I tried this but this didn't help me:

for ( let dataKey in data ) {
  if (dataKey === 'profile_applicant') {
    for (let previewKey in data[dataKey]) {
      formData.append(`${previewKey}`, data[dataKey][previewKey]);
    }
  } else {
    formData.append(dataKey, data[dataKey]);
  }
}

Server console - console.log(req.body):

first_name: test

last_name: test

date_of_birth: test

last_contact: test

files: [object Object],[object Object]


Solution

  • I hope I can help, I did it in a simpler way and I believe it works for all hypotheses, please test.

    If it doesn't fit your use case, please comment so I can edit my answer.

    Full Code:

    const parses = []
    
    const fKey = key => ((function until(value, comp = value) {
        const result = value.replace(/\.([A-z0-9]*)(\.|$)/, '[$1]$2')
    
        return comp !== result ? until(result, value) : result
    })(key))
    
    function populateFormData(values, form = new FormData(), base = '') {
        Object.keys(values).forEach(key => {
            const value = values[key]
    
            if (typeof value == 'string' ||
                typeof value == 'number' ||
                typeof value == 'boolean' ||
                value instanceof File ||
                value instanceof Blob)
            {
                form.append(fKey(`${base}${key}`), value)
                parses.push({
                    key: `${fKey(`${base}${key}`)}`,
                    value
                })
            } 
            else if (typeof value == 'object') 
            {
                populateFormData(value, form, `${base}${key}.`)
            }
        })
        
        return form;
    }
    
    populateFormData({
        title: 'Lucas',
        text: 'Is good :)',
        preview: {
            p_title: 'I am a P title',
            p_text: 'I am a P text',
            test: {
                example: 2,
                my: {
                    obj: [
                        'eba',
                        {
                            hyper: 'text'
                        },
                        123
                    ],
                    yes: true
                }
            }
        }
    })
    
    console.log(parses)