5

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?

1
  • What format does the server-side process expect for the category? Is it expecting a JSON array or multiple category entries? Commented Dec 17, 2020 at 6:39

3 Answers 3

6

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)
  })

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer. It works like a charm.
0

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"]

Comments

-3

Object array passes values

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.