1

I am using axios to upload multiple files and some other stuff. Among this other stuff are arrays of integers (from checkboxes) and some boolean values.

At first I tried this:

axios.post(this.route, {
    name: this.name,
    ...
    photos: this.photos
})

And everything was perfect except that the backend received the photos as empty objects. So I tried the following

let formData = new FormData()
formData.append('name', this.name)
...
for(let i = 0; i < this.photos.length; i++) {
     let photo = this.photos[i]

     formData.append('photos['+i+']', photo)
}
axios.post(this.route, formData)

And the photos worked just fine, but other data like arrays and boolean values from radios started coming wrong. FormData transforms them into strin, and before the backend was receiving them like arrays and booleans directly, I want that. I am using Laravel as backend and the validations do not pass that way.

2 Answers 2

1

If you want to upload files and other structured JSON data, then you will need to manually JSON-stringify all the other data alongside the files.

Here's an example:

const fd = new FormData()

// Include file
fd.append('photo', file)

// Include JSON
fd.append('data', JSON.stringify({
  name: 'Bob',
  age: 20,
  registered: true,
})

axios.post('/users', fd)

On the server you will also need to manually JSON-parse the data field using json_decode (sorry I'm not familiar with Laravel or PHP).

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

2 Comments

This is hybrid solution. Generally, when 3rd-party server accepts form-data it takes all of them in plain standard form without parsing from JSON. You should also follow the standards even if you have access to both FE and BE. The request should be either form-data of json and not both of them.
Of course you should preference key-value form data pairs, but if you want to send complex structured data that cannot be represented as such, then JSON encoding is a good solution.
0

I managed to make the formdata send the data the way I want to. I wish there was a simpler way but here's what I've done.

        let formData = new FormData()
        formData.append('name', this.name)
        formData.append('phone', this.phone)
        formData.append('email', this.email)
        formData.append('house_state', this.house_state)

        // The boolean values were passed as "true" or "false" but now I pass them as "0" or "1" which is strill a string but Laravel recognizes it as an indicator of true or false
        formData.append('has_lived_soon', this.has_lived_soon ? 1 : 0)
        formData.append('can_rent_now', this.can_rent_now ? 1 : 0)

        formData.append('beds_count', this.beds_count)
        formData.append('seasonality', this.seasonality)

        // Here's what I do for the arrays
        for(let extra of this.extras_values) {
            formData.append('extras[]', extra)
        }

        formData.append('estate_issues', this.estate_issues ? 1 : 0)
        formData.append('road_state', this.road_state)
        formData.append('usability', this.usability ? 1 : 0)

        for(let heating_method of this.heating_values) {
            formData.append('heating_methods[]', heating_method)
        }

        formData.append('heating_other', this.heating_other)
        formData.append('address', this.address)

        for(let i = 0; i < this.photos.length; i++) {
            let photo = this.photos[i]

            formData.append('photos['+i+']', photo)
        }

        axios.post(this.route, formData)
            .then(function(response) {
                console.log(response.data)
            })
            .catch(function(error) {
                app.errors = error.response.data.errors
            })

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.