4

I'm using vue.js 2.1 and Laravel 5.4 to upload a file from a component without a form.

Problem: On the server side, this statement return $request->file('my_file'); returns null. Why?

This is how the vue component looks like:

<template>
    <input id="my_file" type="file" @change="fileChanged($event)">
    <button v-if="my_file" @click="update">Upload</button>
</template>

<script>
export default {
    data () {
        return {
            my_file: null,
        }
    },

    methods: {
        fileChanged(e) {
            var files = e.target.files || e.dataTransfer.files;
            if (!files.length)
                return;
            this.createImage(files[0]);
        },

        createImage(file) {
            var image = new Image();
            var reader = new FileReader();
            var vm = this;

            reader.onload = (e) => {
                vm.my_file = e.target.result;
            };
            reader.readAsDataURL(file);
        },

        update() {
            axios.put('/api/update/', {
                my_file: this.my_file,
            })
            .then(response => {
                console.log(response.data);
            })
            .catch(error => {
                console.log(error);
            });
        }
    }
}
</script>

On the server side, I have the following method:

public function update(Request $request)
{
    return $request->file('my_file');

    // $request->file('my_file')->store();
}

What am I missing? So I can use the function $request->file('my_file')->store(); provided by Laravel to upload the file.

EDIT I've changed the http verb from put to post like so:

trySomeThing () {
    var data = new FormData();
    var file = this.$refs.fileInput.files[0];
    data.append('attachment_file', file);
    data.append('msg', 'hello');

    axios.post('/api/try', data)
        .then(response => {
            console.log(response.data)
        });
},

On the controller, I have:

public function try(Request $request)
{
    if ($request->hasFile('my_file')) {
        $file = $request->file('my_file');
        //$file->getFilename();
        return var_dump($file);
    } else {
        return var_dump($_POST);
    }
}

The request header contains: request

The returned response shows this:

response

2

2 Answers 2

3

First add a Vue reference to your file input.

<input id="my_file" type="file" @change="fileChanged($event)" ref="fileInput">

Then update your update method:

update() {
    var data = new FormData()
    var file = this.$refs.fileInput.files[0]
    data.append('my_file', file)
    axios.put('/api/update/', data)     
    .then(response => {
        console.log(response.data)
    })
    .catch(error => {
        console.log(error)
    });
}

In your laravel application:

if ($request->hasFile('my_file')) {
   $file = $request->file('my_file');
   dd($file);
}

For more info: Laravel documentation

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

10 Comments

How do I retrieve the data from the server side? I tried to return $request->my_file; but null is returned. On chrome devTools, I see that the request sent contains : ------WebKitFormBoundary9lOFAy36UFyjOmoh Content-Disposition: form-data; name="attachment_file"; filename="794a4be39f0b96b4d5787e3e31f8b622.jpg" Content-Type: image/jpeg ------WebKitFormBoundary9lOFAy36UFyjOmoh
I've added an else to your php test. It returns what is in the else block. Which means $request->hasFile('my_file') returned false.
please see my question edit. I even tried with post. php doesn't get it.
@Warrio can you try checking for $request->hasFile('attachement_file') ?
@Ikbel:FormData doesn't work with the verb PUT :\ but with POST!!
|
0

Your view should look something like this

<template>
<div class="row">
    <div class="col-md-12">
        <div class="col-md-2">
            <img :src="image" class="img-responsive">
        </div>
        <div class="col-md-8">
            <input type="file" v-on:change="onFileChange" class="form-control">
        </div>
        <div class="col-md-2">
            <button class="btn btn-success btn-block" @click="upload">Upload</button>
        </div>
       </div>
   </div>
</template>
<style scoped>
img{
    max-height: 36px;
}
</style>
<script>
    export default{
    data(){
        return {
            image: ''
        }
    },
    methods: {
        onFileChange(e) {
            let files = e.target.files || e.dataTransfer.files;
            if (!files.length)
                return;
            this.createImage(files[0]);
        },
        createImage(file) {
            let reader = new FileReader();
            let vm = this;
            reader.onload = (e) => {
                vm.image = e.target.result;
            };
            reader.readAsDataURL(file);
        },
        upload(){
            axios.post('/api/upload',{image: this.image}).then(response => {

            });
        }
    }
}
</script>

3 Comments

yes, I guess if it worked for him, it must work also for me.. I'll make a new project and give it another try from scratch and see the difference with mine.
@Warrio I am not using any form here.
I created a new project with your suggested code. Unfortunately it returns null again. Here is a link to the repository git clone [email protected]:warrio4/pr1.git Please have a look

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.