TheBlueDragon's avatar

how to deal with upload input with VueJs ?

hello iam trying to upload file and post the request to my controller

but the response give me that

image field required and when i try to debug its show that the image input was empty !!

<input type="file" name="image" id="image" class="form-control" v-model="newInput.image"> 

in my js

the data

newInput: { name: '', image: ''},

the method

onSubmitForm: function(e) {
            e.preventDefault();
            var input = this.newInput;
            this.newInput = { name: '', image: ''};
            var category = {
                text : input.name,
            };
            console.log(input);
            this.Categories.push(category);
            this.$http.post(this.link,input);
        },

normal text input is send without an issue but for upload i dono why

0 likes
19 replies
TheBlueDragon's avatar

i try to do like this

this.newInput.image = $('input[type=file]').val().split('\\').pop();

the console for the input

console.log(input);

the result is

Object {name: "Small Car2", image: "db-pubserv - Copy.png"}

but the post request give me

POST http://localhost:8000/admin/categories 500 (Internal Server Error)

and in the network tab the response show

FatalErrorException in CategoriesController.php line 46:
Call to a member function getClientOriginalExtension() on a non-object

and this is my store method

public function store(CategoryRequest $request)
    {
        $input = $request->all();
        $extension = $input['image']->getClientOriginalExtension();
        $filename = str_random(5);
        $image = $filename.'.'.$extension;
        Storage::disk('local')->put($image, File::get($input['image']));
        $input['image']->move(public_path().'/images/categories/', $image);
        Storage::delete($image);
        $input['image'] = public_path().'/images/categories/'.$image;
        Category::create($input);

        return redirect()->action('CategoriesController@index');
    }

normal request by

category/create

and post as normal request give me 200 response and the data stored without any issue

so here why i have this issue

is it bcuz its a file name with the extension ??

so what i did is to comment the line where its need to grab the extension

then i got an issue where

File does not exist at path db-pubserv - Copy.png

thats mean the file didnt upload the temporary folder as normal request

so how to solve this ??

iam totally new to js and jquery all what iam doing is to read some jquery codes and try to implement it in my vuejs code and try to do some work with it so excuse me if iam asking to much >_<

TheBlueDragon's avatar

i try to use it with the fake path

$('input[type=file]').val()

but it give me the response

File does not exist at path C:\fakepath\db-pubserv - Copy.png
TheBlueDragon's avatar

@strategicsdemexico

      <form id="link" name="link" value="categories" method="POST" v-on="submit: onSubmitForm" enctype="multipart/form-data">
              <div class="form-group">
                  <label for="name">
                      Category Name:
                  </label>
                  <input type="text" name="name" id="name" class="form-control" v-model="newInput.name">
              </div>
              <div class="form-group">
                  <label for="image">
                      Category Image:
                  </label>
                  <input type="file" name="image" id="image" class="form-control" v-model="newInput.image">
              </div>
              <div class="form-group">
                  <button type="submit" class="btn btn-default">
                      Add Category
                  </button>
              </div>
          </form>
strategicsdemexico's avatar

What I usually do before anything, I test my forms making the post request normally, and see that everything works fine on the server side! if you do that and everything goes well! ok let's review the vue.js code and see why is not completing the process. so try that! @TheBlueDragon

strategicsdemexico's avatar

Try that.. add the v-el="fileInput"

<input type="file" v-el="fileInput" id="image" class="form-control" v-model="newInput.image"> 

On the vue.js

onSubmitForm: function(e) {
    e.preventDefault();
    var input = this.newInput;
    this.newInput = { name: '', image: ''};
    var category = {
        text : input.name,
    };
    input.image = this.$$.fileInput.files; // Get the input as the DOM and get the files, With the v-model you are getting the name of the file
    console.log(input);
    this.Categories.push(category);
    this.$http.post(this.link,input);
},
TheBlueDragon's avatar

@b3zman41 i will read it now

@strategicsdemexico i use the code its give me

is_file() expects parameter 1 to be a valid path, array given

when i try to dd($input['image']) in my controller

its give me a result of this

array:2 [
 0 => []
 "length" => 1
]
strategicsdemexico's avatar

@TheBlueDragon Did you found the solution? I had been busy the rest of my day! I'll try some example tonight and I'll let you know if I found the solution! ok

TheBlueDragon's avatar

@strategicsdemexico @sylar @b3zman41

i try to do the following

  onSubmitForm: function(e) {
        e.preventDefault();
        var form = document.querySelector('#image');
        var file = form.files[0];
        var oData = new FormData();
        var im = oData.append("image", file)
        console.log(im);
        this.$http.post(this.link,oData)

  }

in my controller i use the default Request class

and i just dd($request->all())

so i get the following

the data was send like this

------WebKitFormBoundaryVam2RkEHRiMXIj3s
Content-Disposition: form-data; name="image"; filename="db-pubserv.png"
Content-Type: image/png


------WebKitFormBoundaryVam2RkEHRiMXIj3s--

as i say above i use dd() so i got this

array:1 [ "image" => UploadedFile {#28 -test: false -originalName: "db-pubserv.png" -mimeType: "image/png" -size: 72109 -error: 0 } ]

but how i can get the path and store it in my server ??

sylar's avatar

Go to your store method and just dump good old $_FILES and you will see all info about file. Next

 $imageName = $request->file('image')->getClientOriginalName();
    $request->file('image')->move(
        base_path() . '/public/', $imageName
    );
TheBlueDragon's avatar

yes i got this after trying but the problem with other data like the input of the text field iam trying to get them because when i select the id of the form i dont get any good information but with selecting the id of the image file input i can get the tmp_file

TheBlueDragon's avatar

@sylar

after some searching and try i just try to get this

oData.append('image',file);
    oData.append("category_name", this.newInput.name)

and in my dd() i got this as i make the dd() as an array

[
            'request'=> $request->all(),
            'tmp_path'=>$_FILES
        ]

array:2 [ "request" => array:2 [ "category_name" => "Small Car2" "image" => UploadedFile {#28 -test: false -originalName: "db-pubserv.png" -mimeType: "image/png" -size: 72109 -error: 0 } ] "tmp_path" => array:1 [ "image" => array:5 [ "name" => "db-pubserv.png" "type" => "image/png" "tmp_name" => "C:\wamp\tmp\php4AFF.tmp" "error" => 0 "size" => 72109 ] ] ]

now iam trying to make the validate and get all the important data

kuroski's avatar

I'm currently using this solution:

<!-- my-form.html -->
.
.
.
<input type="file" id="image" v-el="fileInput">
.
.
.
// my-app.js
.
.
.
methods: {
    submitForm: function(e) {
        e.preventDefault();

         var formData = new FormData();
         formData.append('image', this.$$.fileInput.files[0]);
         formData.append('name', this.formData.name);
         formData.append('email', this.formData.email);
         formData.append('otherField', this.formData.otherField);

         this.$http.post('/my/post/url', formData, function (data, status, request) {
             console.log('success');
         }).error(function (data, status, request) {
             console.log('error');
         });
    }
}
// my-controller.php
.
.
.
public function myFunction(Request $request)
{
    dd($request->all(), $request->hasFile('image'), $request->file('image'));
}
4 likes
pnkjSuthar's avatar

For multiple file upload you can use this.

<!-- my-form.html -->
.
.
.
<input type="file" id="image" v-el="moreImage" multiple>
.
.
.

//for multple file upload in your js file

var files = this.$$.moreImage.files;
for(var key in files){
          formData.append('more_image['+key+']', files[key]);
  }
//in your controller you can do like this
$moreImages = Input::get('more_image') ;
foreach($moreImages as $image){
     //wirte your code here
}
2 likes

Please or to participate in this conversation.