Usoof
Usoof

Reputation: 713

sending array data with multipart/form-data post request in Axios vue.js

I'm sending a post request from vue.js project using Axios and it contains a file upload, which requires me to use FormData, I found a nice answer that helped me with FormData:

const getFormData = object => Object.keys(object).reduce((formData, key) => {
     formData.append(key, object[key]);
     return formData;
}, new FormData());

and for the headers: headers: { 'Content-Type': 'multipart/form-data'}.

The POST call looks like this:

axios.post("http://127.0.0.1:8000/api/document/",
      getFormData(this.documentData),
      {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      })
      .then(response => {
        console.log("Successfully uploaded: ", response.data)
      })
      .catch(err => {
        console.log("error occured: ", err)
      })

This is the data I'm sending:

documentData: {
      name: '',
      file: '',
      version: '',
      company: '',
      author: '',
      category: []
    }

When sending the data with single category id, it works fine, but when I send multiple category ids the following error shows:

"category": [
    "Incorrect type. Expected pk value, received str."
]

How can I solve this problem?

Upvotes: 5

Views: 16171

Answers (3)

Nashaat Mohamed
Nashaat Mohamed

Reputation: 331

you can use json stringfy , I am using it also with vue app

formData.append("TeamMembers", JSON.stringify(this.TeamMembers));
 axios
 .post("/api/pro", formData, {
  onUploadProgress: (progressEvent) => console.log(progressEvent.loaded),
  headers: { "Content-Type": "multipart/form-data", },  })

Team members is an array .. and you can parse it in the other side this way

const myArr = ['bacon', 'lettuce', 'tomatoes'];

const myArrStr = JSON.stringify(myArr);

console.log(myArrStr);
// "["shark","fish","dolphin"]"

console.log(JSON.parse(myArrStr));
// ["shark","fish","dolphin"]

Upvotes: 0

Phil
Phil

Reputation: 164970

Assuming your server-side process is expecting multiple, repeated field names for array types, you'll want something like this

const getFormData = object => Object.entries(object).reduce((fd, [ key, val ]) => {
  if (Array.isArray(val)) {
    val.forEach(v => fd.append(key, v))
  } else {
    fd.append(key, val)
  }
  return fd
}, new FormData());

Some server-side processes (PHP for example) require that collection-type fields include a [] suffix. If that's what you're working with, change this line

val.forEach(v => fd.append(`${key}[]`, v))

Also, when sending FormData from your browser, do not manually set the Content-type header. Your browser will do this for you, including the required boundary tokens

axios.post("http://127.0.0.1:8000/api/document/", getFormData(this.documentData))
  .then(response => {
    console.log("Successfully uploaded: ", response.data)
  })
  .catch(err => {
    console.error("error occurred: ", err)
  })

Upvotes: 6

zcw
zcw

Reputation: 14

Object array passes values

    
var arr=['上海','北京'];
var formData = new FormData();
for (var i = 0; i < arr.length; i++) {
 formData.append('city[]',arr[i]);
}

Upvotes: -3

Related Questions