cejowisz's avatar

Blob upload with axios fail in Laravel

I have been trying to upload files using axios, the payload on the console network tab looks great but the files appear to be empty on the Laravel side.

Below is the response I get from $request->all()

 "feedback": {
   "description": "there is not a friend",
   "displays": [
     "Lagos -\r\n Ikoyi"
   ],
   "messages": [
     {
       "text": "this is an unexpected result",
       "startTime": "2018-02-20T11:11:01.404Z",
       "endTime": "2018-02-20T11:11:01.411Z",
       "image": {},
       "video": {}
     }
   ]
 }
}

Below is the send method:

```submit() {

               const data = new FormData();
               data.append('description', this.description);
               for (let index in this.boards) {
                   if (this.boards.hasOwnProperty(index)) {
                       data.append('displays[' + index + ']', this.boards[index]);
                   }
               }
               for (let index in this.messages) {
                   if (this.messages.hasOwnProperty(index)) {
                       data.append('messages[' + index + '][text]', this.messages[index].text);
                       data.append('messages[' + index + '][image]', this.messages[index].imageBlob);
                       data.append('messages[' + index + '][video]', this.messages[index].videoBlob);
                       data.append('messages[' + index + '][startTime]', this.messages[index].startTime);
                       data.append('messages[' + index + '][endTime]', this.messages[index].endTime);
                   }
               }

               axios.post('/campaign/', data, {
                   headers: {
                       'accept': 'application/json',
                       'Accept-Language': 'en-US,en;q=0.8',
                       'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
                   }
               }).then(response => {
                   this.feedback = response.data;
               }).catch(error=>{
                   this.errors = error
               });
           }

Please, how can I work around that?
0 likes
8 replies
ejdelmonico's avatar

What is your file size limit(max_post_size)? That could be blocking the blob content if it exceeds the max.

Cronix's avatar

also in your headers, you are using backticks instead of single quotes on the

'Content-Type': `multipart/form-data; boundary=${data._boundary}`,

You're using single quotes on the other headers

'accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.8',
cejowisz's avatar

It is 32M. I guess that is large enough because what I'm uploading is around 24M

ejdelmonico's avatar

file size is always the first thing that I check in situations like this. What does the form look like? I am wondering if the multipart/form-data is getting sent correctly. Also, what is the column definition in your migration? Over 16M, your column would need to be LONGBLOB (16M to 4GB). Regular BLOB type only holds 64kb.

cejowisz's avatar

I have increased the max file size to 128M in php.ini

I'm yet to get the file in the controller via $request->file('image')so, it is not time for validation yet or storage.

If the multipart/form-data was not sent correctly, what could be another alternative to send it?

Below is how the form looks like @ejdelmonico It is a child component of the main form.

<template>
   <div>
       <div class="row">
           <div class="input-field col s12">
                <a class="waves-effect waves-light btn blue right" href="#modal1">Message</a>
           </div>
       </div>

       <div id="modal1" class="modal">
           <div class="modal-content" style="height: 700px;">
               <h5>Add Message</h5>

               <div class="row">
                   <div class="input-field col s12">
                       <textarea name="text" id="input-message" v-model="text" class="materialize-textarea"  data-length="200"></textarea>
                       <label for="input-message">Message</label>
                   </div>
               </div>

               <div class="row">
                   <div class="input-field col m6">
                       <datetime
                               placeholder="Select start date"
                               type="datetime"
                               v-model="startTime"
                               input-format="DD-MM-YYYY HH:mm"
                               input-class="my-input-class"
                               auto-continue
                               auto-close
                               required>

                       </datetime>

                   </div>
                   <div class="input-field col m6">
                       <datetime
                               placeholder="Select end date"
                               type="datetime"
                               v-model="endTime"
                               input-format="DD-MM-YYYY HH:mm"
                               input-class="my-input-class"
                               auto-continue
                               auto-close
                               required>

                       </datetime>
                   </div>
               </div>

               <div class="row">
                   <div class="col m6">
                       <div class="file-field input-field">
                           <div class="btn blue">
                               <span>Image</span>
                               <input type="file" id="input-image" name="image" @change="refreshImage">
                               <!--<img :src="imageUrl" height="150">-->
                           </div>
                           <div class="file-path-wrapper">
                               <input class="file-path validate" type="text" placeholder="Upload image">
                           </div>
                           <img id="image-thumb" name="image-thumb" width="100px" class="image-thumbnail img-responsive" :src="imageUrl"/>
                       </div>
                   </div>

                   <div class="col m6">
                       <div class="file-field input-field">
                           <div class="btn blue">
                               <span>Video</span>
                               <input type="file" name="video" id="input-video" @change="refreshVideo">
                           </div>
                           <div class="file-path-wrapper">
                               <input class="file-path validate" type="text" placeholder="Upload video">
                           </div>
                           <video id="video-preview" width="100px" type="video/mp4" controls class="video-preview img-responsive" :src="videoUrl"/>
                       </div>
                   </div>
               </div>

               <div class="row">
                   <div class="input-field col s12">
                       <button @click.prevent="addMessage" class="modal-action modal-close waves-effect waves-light btn blue right">
                           Add Message
                       </button>
                   </div>
               </div>
           </div>

       </div>

   </div>


</template>
cejowisz's avatar

This is the parent component.

<template>
    <div>
        <form class="form-horizontal" enctype="multipart/form-data">
            <div class="row">
                <div class="input-field col s12">
                    <input id="description" v-model="description" type="text" class="validate">
                    <label for="description">Description</label>
                </div>
            </div>

            <div class="row">
                <div class="input-field col s12">
                    <div>
                        <multiselect
                            v-model="boards"
                            :options="option"
                            :multiple="true"
                            :close-on-select="true"
                            :clear-on-select="false"
                            :hide-selected="true"
                            :preserve-search="false">
                        </multiselect>

                    </div>
                </div>
            </div>

            <campaign-modal v-on:added-message="addedMessage"></campaign-modal>


            <table class="striped highlight">
                <thead>
                    <tr>
                        <th width="20%">Message </th>
                        <th width="25%">Image </th>
                        <th width="25%">Video </th>
                        <th width="10%">Start</th>
                        <th width="10%">End</th>
                        <th width="10%">Action</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(message, index) in messages" v-cloak>
                        <td>
                            {{ message.text }}
                            <input type="hidden" name="message_text[]" v-model="message.text"/>
                        </td>
                        <td>
                            <div class="image-container">
                                <img v-if="message.image" class="responsive-img" :src="message.image"/>
                            </div>
                            <input type="hidden" name="message_image[]" :value="message.image"/>
                        </td>
                        <td>
                            <div class="video-container">
                                <video v-if="message.video" preload="none" width="200px" type="video/mp4" controls :src="message.video"></video>
                            </div>
                            <input type="hidden" name="message_video[]" :value="message.video"/>
                        </td>
                        <td>
                            {{ message.startTime }}
                            <input type="hidden" name="start_time[]" :value="message.startTime"/>
                        </td>
                        <td>
                            {{ message.endTime }}
                            <input type="hidden" name="end_time[]" :value="message.endTime"/>
                        </td>
                        <td class="column operation">
                            <button @click="deleteMessage" class="btn red">Delete</button>
                            <input type="hidden" name="message_id[]" :value="message.id"/>
                        </td>
                    </tr>
                    <tr class="empty-row waka" v-show="messages.length == 0">
                        <td colspan="6">No messages added. Click above to add a new message.</td>
                    </tr>
                </tbody>
            </table>
            <div v-show="messages.length > 0" class="row">
                <div class="input-field col s12">
                    <button @click.prevent="submit" type="submit" class="waves-effect waves-light btn blue">
                        Submit Campaign
                    </button>
                </div>
            </div>
        </form>

        <pre>{{ feedback }}</pre>
    </div>
</template>
ejdelmonico's avatar

How is the parent (form) getting the values form the child (form upload)? If the parent isn't receiving the child data in the form, then the file upload data will probably be null or you may only be getting the name or whatever depending on your code.

Please or to participate in this conversation.