Upload multiple file with vue js and axios - laravel

I am trying to upload multiple images using vuejs and axios but on server side i am getting empty object. I added multipart/form-data in header but still empty object.
submitFiles() {
/*
Initialize the form data
*/
let formData = new FormData();
/*
Iteate over any file sent over appending the files
to the form data.
*/
for( var i = 0; i < this.files.length; i++ ){
let file = this.files[i];
console.log(file);
formData.append('files[' + i + ']', file);
}
/*`enter code here`
Make the request to the POST /file-drag-drop URL
*/
axios.post( '/fileupload',
formData,
{
headers: {
'Content-Type': 'multipart/form-data'
},
}
).then(function(){
})
.catch(function(){
});
},
HTML:
<form method="post" action="#" id="" enctype="multipart/form-data">
<div class="form-group files text-center" ref="fileform">
<input type="file" multiple="multiple">
<span id='val'></span>
<a class="btn" #click="submitFiles()" id='button'>Upload Photo</a>
<h6>DRAG & DROP FILE HERE</h6>
</div>
My Server side code:
class FileSettingsController extends Controller
{
public function upload(Request $request){
return $request->all();
}
}
Output:
{files: [{}]}
files: [{}]
0: {}
Console.log() result:
File(2838972) {name: "540340.jpg", lastModified: 1525262356769, lastModifiedDate: Wed May 02 2018 17:29:16 GMT+0530 (India Standard Time), webkitRelativePath: "", size: 2838972, …}

You forgot to use $refs. Add ref to your input:
<input type="file" ref="file" multiple="multiple">
Next, access your files like this:
submitFiles() {
const formData = new FormData();
for (var i = 0; i < this.$refs.file.files.length; i++ ){
let file = this.$refs.file.files[i];
formData.append('files[' + i + ']', file);
}
axios.post('/fileupload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
}
).then(function(){
})
.catch(function(){
});
},
This should be works.

If anyone wondering, "How can I send also data with it", there you go:
formData.append('name[' + this.name + ']', name);
formData.getAll('files', 'name');

For Composition API this should work:
const files = ref([])
function save() {
let formData = new FormData()
for (let file of files.value) {
formData.append('files', file)
}
axios.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then((response) => {
})
}

Related

Asp.net core - How to implement realtime using signalR

I am adding a comments part in my project, I would like to use real-time using signalR.
I'm using Ajax for adding comments, and I want to refresh data for all users after the comment inserts into the database.
This is my code in Razor view :
<form asp-action="SendComment" asp-controller="Home" asp-route-subId="#Model.Subject.Id"
asp-route-AccountName="#User.Identity.Name" onsubmit="return jQueryAjaxPost(this);">
<textarea name="comment" id="myTextbox" required class="form-control mb-3" rows="3" cols="1" placeholder="اكتب هنا"></textarea>
<div class="d-flex align-items-center">
<button type="submit" id="myBtn" class="btn bg-blue-400 btn-labeled btn-labeled-right ml-auto"><b><i class="icon-paperplane"></i></b> ارسال</button>
</div>
</form>
Ajax code :
jQueryAjaxPost = form => {
try {
$.ajax({
type: 'POST',
url: form.action,
data: new FormData(form),
contentType: false,
processData: false,
success: function (res) {
if (res.isValid) {
$('#view-all').html(res.html)
}
else
$('#form-modal .modal-body').html(res.html);
},
error: function (err) {
console.log(err)
}
})
//to prevent default form submit event
return false;
} catch (ex) {
console.log(ex)
}
}
signalR code (Not finished)
<reference path="../lib/signalr/browser/signalr.js" />
$(() => {
let connection = new signalR.HubConnectionBuilder().withUrl("/signalServer").build();
connection.start();
connection.on("refreshData", function () {
loadData();
});
loadData();
function loadData() {
debugger;
$.ajax({
type: 'GET',
url: '#Url.Action("refreshComments","Home")',
success: function (res) {
$('#view-all').html(res);
}
})
}
});
Code-behind :
var newComment = new CourseComment
{
Comment = comment,
Date = DateTime.Now,
ApplicationUser = user,
SubjectId = subId,
CreatedDate = DateTime.Now
};
_courseCommnt.Entity.Insert(newComment);
await _courseCommnt.SaveAsync();
await _signalR.Clients.All.SendAsync("refreshData");
_toastNotification.AddSuccessToastMessage("تم ارسال التعليق بنجاح");
var courseComments = await _courseCommnt.Entity.GetAll().Include(a => a.ApplicationUser)
.Where(a => a.SubjectId == subId).OrderByDescending(a => a.Date).AsNoTracking().ToListAsync();
var vm = new HomeViewModel
{
CourseComments = courseComments
};
return Json(new
{
isValid = true,
html = Helper.RenderRazorViewToString(this, "_SubjectComments", vm)
});

How to upload audio file from Vue.js to Laravel?

I tried uploading an audio file like an image, but it didn't work. How do I extract data from an audio file and send it to Laravel?
<input
type="file"
class="user-edit-form browse-file"
accept=".mp3,audio/*"
#change="uploadSong"
>
uploadSong (e) {
console.log(e)
this.songUpload = e.target.files[0]
if (!this.songUpload.length) {
return
}
this.createSong(this.songUpload[0])
},
createSong (file) {
let reader = new FileReader()
let vm = this
reader.onload = (e) => {
vm.song = e.target.result
console.log(e.target.result)
}
reader.readAsDataURL(file)
}
Input:
<input type="file" id="inputName" name="inputName" v-on:change="fileData(this)" />
On Chnage:
fileData(element){
var filedata = $(element).prop("files")[0];
var fileName = file_data.name;
var fileExtension = fileName.split('.').pop().toLowerCase();
}
You can try below code:
Input:
<input type="file" id="file" ref="file" v-on:change="handleFileUpload()"/>
on file change:
handleFileUpload(){
this.file = this.$refs.file.files[0];
}
Finally on form submit:
submitAudioFile(){
let formData = new FormData();
// add file
formData.append('file', this.file);
axios.post( '/upload',
formData,
{
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
}
}
)
.then(function(){
console.log('success');
})
.catch(function(){
console.log('failed');
});

Upload file with Vuejs

i'm working in Laravel. i need to upload file with Vuejs. but it's not working. I add this code:
Blade (File upload):
<input class="form-control" type="file" >
Script Vuejs :
var app = new Vue({
el: '#app',
data: {
person: {
id: 0,
user_name:'',
position_id:'',
image:'',
},
},
methods: {
addPerson: function () {
axios.post('/addperson', this.person)
.then(response => {
console.log(response.data);
if (response.data.etat) {
this.person = {
id: 0,
user_name: response.data.etat.user_name,
position_name: response.data.etat.position_id,
image: response.data.etat.image
};
}
})
.catch(error => {
console.log('errors: ', error)
})
},
Controller:
public function addPerson(Request $request){
$person = new Person;
$person->user_name=$request->user_name;
$person->position_id=$request->position_id;
if($request->hasFile('photo')){
$person->image= $request->image->store('image');
}
$person->save();
return back()->with('success', 'New Position added successfully.');
My Axios post function is working without the image upload line code. I just don't know how to add the upload code.
Thank you if someone can help.
In your blade file
<input type="file" #change="onFileChange" name="id_image" id="id_image" class="inputFile">
In your vue.js file, under 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();
reader.onload = (e) => {
this.person.image = e.target.result;
};
reader.readAsDataURL(file);
},
That should allow your axios code to upload the image. Note, that it uploads in base64, so if you need validators you will have to create a custom Validator for base64 images.
I struggled to find out how to do this, but I've now found a way. Hopefully this makes someones life easier(I have the uploadUserImage method in a mixin):
HTML:
<input type="file" #change="uploadImage($event)">
JS:
uploadImage (e) {
this.file = e.currentTarget.files[0]
let formData = new FormData()
formData.append('img', this.file)
this.uploadUserImage(formData)
}
uploadUserImage: function (formData) {
axios.post('http://snowdon-backend.local:8000/api/users/img', formData,
{
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(function (response) {
console.log(response)
})
}
Make sure file is set in the data method as well:
data () {
return {
file: ''
}
}

Updating object in vueJS

I'm creating an upload VueJS component and I've this portion to display the images in the images object:
<div class="row">
<figure class="col-md-3" v-for="image in images">
<img :src="'/'+image.image" :alt="image.description+'-'+image.image" class="img-responsive"
style="width:100%;">
</figure>
</div>
I want to know if there's a way yo image the images after every successful upload and to get the newly uploaded images.
Here's the the method I'm using to submit the images :
props: ['data'],
data() {
return {
files: [],
slug: this.data.slug,
id: this.data.part.id,
images : this.data.part.images
}
},
methods: {
submitFiles() {
let formData = new FormData();
for (let i = 0; i < this.files.length; i++) {
let file = this.files[i];
formData.append('files[' + i + ']', file);
}
axios.post('/dashboard/galleries/',
formData,
{
headers: {
'Content-Type': 'multipart/form-data'
}
}
).then(function () {
console.log('SUCCESS!!');
})
.catch(function () {
console.log('FAILURE!!');
});
}
Thanks to everyone for helping.
what you can do is after uploading your files is to return a response containing your images urls like so:
return response()->json(['images' => $images]);
and then in your .then block you can assign the response to your images piece of data like so:
axios.post('/dashboard/galleries/',
formData,
{
headers: {
'Content-Type': 'multipart/form-data'
}
}
).then(function (res) {
this.images = res.data.images;
})
update
since the data is going to change when we get the response we will need to use watch like so:
props: ...,
methods: ...,
watch: {
images: function(val) {
this.images = val;
}
}
use this https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL to display image from base64 string. There is a simple example.

Angular 2 Multipart AJAX Upload

I'm using Angular 2 with Spring MVC. I currently have an Upload component that makes an AJAX call to the Spring backend and returns a response of parsed data from a .csv file.
export class UploadComponent {
uploadFile: function(){
var resp = this;
var data = $('input[type="file"]')[0].files[0];
this.fileupl = data;
var fd = new FormData();
fd.append("file", data);
$.ajax({
url: "uploadFile",
type: "POST",
data: fd,
processData: false,
contentType: false,
success: function(response) {
resp.response = response;
},
error: function(jqXHR, textStatus, errorMessage) {
console.log(errorMessage);
}
});
};
}
This works, I get a valid response back; however, is there a more angular 2 way to pass this file to Spring and receive a response? I've been looking into creating an injectible service and using subscribe, but I've been struggling to get a response back
I ended up doing the following:
import { Component, Injectable } from '#angular/core';
import { Observable} from 'rxjs/Rx';
const URL = 'myuploadURL';
#Component({
selector: 'upload',
templateUrl: 'upload.component.html',
styleUrls: ['upload.component.css']
})
export class UploadComponent {
filetoUpload: Array<File>;
response: {};
constructor() {
this.filetoUpload = [];
}
upload() {
this.makeFileRequest(URL, [], this.filetoUpload).then((result) => {
this.response = result;
}, (error) => {
console.error(error);
});
}
fileChangeEvent(fileInput: any){
this.filetoUpload = <Array<File>> fileInput.target.files;
}
makeFileRequest(url: string, params: Array<string>, files: Array<File>) {
return new Promise((resolve, reject) => {
let formData: any = new FormData();
let xhr = new XMLHttpRequest();
for(let i =0; i < files.length; i++) {
formData.append("file", files[i], files[i].name);
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.response));
} else {
reject(xhr.response);
}
}
};
xhr.open("POST", url, true);
xhr.send(formData);
});
}
}
I can then inject a response into my html like:
<div class="input-group">
<input type="file" id="file" name="file" placeholder="select file" (change)="fileChangeEvent($event)">
<input type="submit" value="upload" (click)="upload()" class="btn btn-primary">
</div>
<div *ngIf="response">
<div class="alert alert-success" role="alert">
<strong>{{response.myResponseObjectProperty | number}}</strong> returned successfully!
</div>
This has support for multiple file uploads. I created it as an injectable service in this plunkr:
https://plnkr.co/edit/wkydlC0dhDXxDuzyiDO3

Resources