0
votes

I Already asked my question on VueJS Forum : https://forum.vuejs.org/t/file-upload-with-formdata-vue-resource/20952/3

But ! For duplicate my chances to success I'll ask you about my problem.

Simply I have a input type file (without form parent node) and I'm trying to upload asynchronously a file with FormData and Vue-resource http to my Laravel 5.5 API Backend..

To test my upload my controller return a JSON response with a dump of my $request.

Well, I have a 200 code and but unfortunetly my response is empty..

Thank you for your helping :)

Request payload here

Client code

export default {
  name: 'profile',
  data () {
    return {
      user: {},
      files: [],
      filepath: false,
      imageData: ''
    }
  },
  mounted () {
    this.user = this.$store.getters.user
  },
  methods: {
    reset: function () {
      this.remove()
    },
    upload: function (e) {
      var data = new FormData()
      var file = this.files[0]

      data.append('test', 1234)
      data.append('avatar', file)

      this.$http({
        url: this.user.actions.updateAvatar,
        body: data,
        method: 'POST',
        responseType: 'json',
        before: function (request) {
          console.log(request)
        }
      })
      .then((response) => {
        console.log(response)
      })
      .catch((errorResponse) => {
        console.log(errorResponse)
      })
    },
    sync: function (e) {
      e.preventDefault()
      this.files = e.target.files || e.dataTransfer.files
      if (!this.files.length) {
        return
      }
      this.createFile(e, this.files[0])
    },
    createFile: function (e, file) {
      this.filepath = URL.createObjectURL(file)
    },
    remove: function () {
      URL.revokeObjectURL(this.filepath)
      this.filepath = false
      this.files = []
      document.getElementById('avatar').value = ''
    }
  }
}
<template>
    <!-- header profile -->
    <div id="profile">
        <section class="container">
            <div class="row">
                <div class="col-lg-8 col-lg-offset-2">
                    <div class="profile">
                        <input type="hidden" name="_method" value="PUT"/>
                        <header>
                            <label for="avatar" class="avatar" v-if="!filepath">
                            <img :src="user.avatar || 'http://placehold.it/50x50'" alt="avatar">
                            </label>
                            <div class="avatar" @click="reset" v-if="filepath">
                                <img :src="filepath" alt="avatar">
                            </div>
                            
<!-- Trigger a preview -->
<input @change="sync" id="avatar" name="avatar" type="file" accept="image/*;" class="hide">
                            
                            <div class="info">
                                <span class="name">John Snow 
                                    <router-link :to="{ name: 'UserSettings' }">
                                        <span class="ico gear"></span>
                                    </router-link>
                                </span>
                                <span class="desc">Une bio de 40 caractères</span>
                                <span class="social">
                                    <span class="ico fb"></span>
                                    <span class="ico tw"></span>
                                </span>
                            </div>
                        </header>
<!-- Trigger upload -->                     
<span @click="upload" class="btn-save" v-if="filepath">
    Enregistrer
</span>
                    </div>
                </div>
                <div class="col-lg-8 col-lg-offset-2">
                    <div class="col-lg-12">
                        <router-link :to="{ name: 'UserPosts' }">
                            <span for="dechet" class="nb-dechet">122 déchêts postés</span>
                        </router-link>
                        |
                        <router-link :to="{ name: 'UserBookmarks' }">
                            <span for="dechet" class="nb-dechet">122 déchêts sauvegardés</span>
                        </router-link>
                        |
                        <router-link :to="{ name: 'UserTrophies' }">
                            <span for="reward" class="nb-dechet">1 trophé obtenu</span> 
                        </router-link>
                    </div>
                </div>
            </div>
        </section>    
        <hr>
        <!-- posts -->
        <section class="container">
            <div class="row">
                <router-view></router-view>
            </div>
        </section>
    </div>
</template>

Server-side code

Route | Dummy Controller

1
can you show me the server side code please?rummykhan
I updated my post :)Daedelus

1 Answers

1
votes

Well there is nothing wrong with your code, its just that response()->json() is not able to convert Illuminate\Http\UploadedFile to json.

Your file is being uploaded, try to check it like

return response()->json([
   'avatar' => $request->file('avatar')->getClientOriginalName()
]);

and you'll get the name of the file in response.

Reason Reason for why it is unable to convert Illuminate\Http\UploadedFile to JSON response is it doesn't implements Illuminate\Contracts\Support\Jsonable