0

I cannot upload multiple images in my Laravel + vue js project..

here is my code below

my vue conponent

<form @submit.prevent="addProduct" enctype="multipart/form-data">
                                <div class="form-group">
                                    <div class="row">
                                        <div class="col-lg-4">
                                            <label for="product_image">Product Image:</label>
                                        </div>
                                        <div class="col-lg-4">
                                            <input type="file" name="pics[]" id="product_image" @change="fieldChange" multiple>
                                            <has-error :form="form" field="product_image"></has-error>
                                        </div>
                                        <div class="col-lg-4">
                                            <img :src="form.product_image" height="70px" width="85px" alt="">
                                        </div>
                                    </div>
                                </div>

</form>

i Used FormData to upload images

    data: function(){
            return{
                attachment:[],
                imageForm : new FormData,
            }
        },
        methods:{
            fieldChange(e){
                let selectedFiles = e.target.files;
                if (!selectedFiles.length) {
                    return false;
                }
                for(let i=0;i<selectedFiles.length;i++){
                    this.attachment.push(selectedFiles[i])
                }
                console.log(this.attachment);
                 //I checked here ang got image arrays
            },
            addProduct:function(){
                for(let i=0;i<this.attachment.length;i++){

                this.imageForm.append('pics[]',this.attachment[i]);

                //When I console.log() this line it says undefined
                }
                axios.post('/save-product',this.form,this.imageForm).then((response)=>{
                        toastr.success('Product Info Added Successfully','Success!');
                    }).catch((error)=>{

                    })
            },
}

my controller here...here I find this error

    public function store(Request $request)
    {
        $uploadedFiles = $request->pics;
        foreach ($uploadedFiles as $file) {
            $file->store(public_path('uploads/products'));
        }
        return response()->json(['status'=>'success'],200);
}

status says 500 error...and in my network I got that error...And says Invalid argument supplied for foreach().

this is my full part of data..

data: function(){
            return{
                form: new Form({
                    product_name:null,
                    product_color:null,
                    publication_status:1,
                    category_id:'',
                    brand_name:null,
                    product_price_regular:null,
                    product_price_discount:null,
                    product_quantity:1,
                    short_description:null,
                    long_description:null,
                    user_name:'Admin',
                    // product_image:[],
                }),
                attachments:[],
                imageForm : new FormData,
            }
        },  

please see this part when I do this other fields saved in database but images do not save... and if i do not add these fields images are saved in database

addProduct(){
                for(let i=0;i<this.attachments.length;i++){
                this.imageForm.append('product_image[]',this.attachments[i]);
                }
                const data = {
                    'product_image':this.product_image,'product_name':this.product_name,'product_color':this.product_color,'category_id':this.category_id,'product_price_regular':this.product_price_regular,'product_price_discount':this.product_price_discount,'short_description':this.short_description,'long_description':this.long_description,'user_name':this.user_name,'publication_status':this.publication_status
                }
                const config= {
           headers:{
                    "Content-Type": "multipart/form-data"
                   } 
                }
                axios.post('/save-product',data,this.imageForm,config).then((response)=>{
                        toastr.success('Product Info Added Successfully','Success!');
                    }).catch((error)=>{

                    })
            },
m.i. shad
  • 5
  • 4

1 Answers1

0

First thing first. Axios parameters are not correctly passed. Axios expects first parameter as route path, second the form data and third is header. Therefor just modify your axios code like below and it will work.

 const config= {
           headers:{
                    "Content-Type": "multipart/form-data"
                   } 
        }
    this.imageForm.append('product_name',this.product_name);
    this.imageForm.append('product_color',this.product_color);

    axios.post('/save-product',this.imageForm,config).then((response)=>{
              toastr.success('Product Info Added Successfully','Success!');
            }).catch((error)=>{

            })
   

I also attached the laravel response image to show that it is working fine. enter image description here

Muhammad Atif Akram
  • 1,204
  • 1
  • 4
  • 12
  • this works perfectly...but how to change directory to public path??? – m.i. shad Apr 11 '21 at 10:24
  • Dear did you tried the laravel asset function ? e.g asset('profiles/image.png') – Muhammad Atif Akram Apr 11 '21 at 10:30
  • no.Can I do it in my controller??? and an addition please... when I submit this form by FormData axios.post('/') did it.But how do I upload other fields when I want to upload them by v-form. – m.i. shad Apr 11 '21 at 10:36
  • public function uploadFile($path,...$files){ $path = ltrim($path,'/'); foreach ($files as $file){ $orginalName = $file->getClientOriginalName(); $newName = time().'_'.$orginalName; $file->move(public_path().'/'.$path,$newName); } } Assume that you have folder profiles inside public directory then just pass file and the path like below. uploadFile('profiles',$file); you can also pass array of files in second argument – Muhammad Atif Akram Apr 11 '21 at 10:40
  • bind v-modal to input field and on submit of form append that values with key. e.g this.imageForm.append('username',this.username) – Muhammad Atif Akram Apr 11 '21 at 10:45
  • do I need to import all my input fields in this.imageForm.append() ??? – m.i. shad Apr 11 '21 at 10:50
  • create variables in data section for each input field. For example you have another field username. Then inside data section, create a variable like username:''. Then bind that to input field. e.g and right before the api call append this variable with key inside formData like this.imageForm.append('username', username) – Muhammad Atif Akram Apr 11 '21 at 10:53
  • Dear I don't have much better experience of using v-form API. As far i know its for validation form by using rules. However, its always good practice to create object with all form values and then pass with axios like. const data = { 'pics':this.pics, 'username':this.username } and then in axios using axios.post(route,data, config) – Muhammad Atif Akram Apr 11 '21 at 11:41
  • I updated my question...please save me this time – m.i. shad Apr 11 '21 at 12:00
  • Ow I need to append then separately ...I never worked with this style...I always used vform...Thank you again...May ALLAH bless you – m.i. shad Apr 11 '21 at 12:11