I am developing SPA using VueJS, Laravel 5.3 and Passport Authentication module.
My Code upto now. and I can get file name selected. Working fine but how to send selected files to make post request to upload the files to the server?
<script>
import {mapState} from 'vuex'
export default{
computed: {
...mapState({
userStore: state => state.userStore
})
},
data () {
return {
fax: {
files: '',
image: ''
}
}
},
methods: {
onFileChange (e) {
this.fax.files = e.target.files || e.dataTransfer.files
if (!this.fax.files.length) {
return
}
console.log(this.fax.files)
}
},
created () {
this.$store.dispatch('setUserDid')
}
}
</script>
<template>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" multiple #change="onFileChange">
<input type="text" name="group" >
<ul>
<li v-for="file in fax.files">
{{ file.name }}
</li>
</ul>
</template>
Upto now, I can get file names displayed on my page using {{fax.files}}. How to make post request so that i can catch the file from my server side (API endpoint)? I tried googling and coding but i could not able to do.
Ok I managed to get this working. Before the file upload I had an array that I was posting via Ajax as you can see below.
I modified it to look like the below in order handle file uploads.
Basically you need to send through a FormData object when uploading files. Uses a FormData object by default when submitting a form - but when only posting a array you need to first append those array values to the FormData object.
You should be able to make sense of the code below...
var formData = new FormData();
jQuery.each(this.comment.file, function(i, file) {
formData.append('file[]', file);
});
formData.append('body', this.comment.body);
formData.append('comments_room_id', this.comment.comments_room_id);
formData.append('id', this.comment.id);
formData.append('name', this.comment.name);
this.$http.post('/api/comment/store', formData).then(function (response) {
Related
I'm trying to upload a file to a laravel backend via axios.
When a user clicks on the file input I get the file object, append it to the formData object post it to the backend, but for some reason, when I try to get the file on the backend I get an empty array.
here is my code:
<template>
<div>
<input type="file" #change="uploadFile" ref="file">
<button #click="submitFile">Upload!</button>
</div>
uploadFile(){
this.Images = this.$refs.file.files[0];
const formData = new FormData();
formData.append('file', this.Images);
const headers = { 'Content-Type': 'multipart/form-data' };
axios.post(this.baseUrl+'test-file-uploads', formData, { headers }).then((res) => {
res.data.files; // binary representation of the file
res.status; // HTTP status
});
}
public function testUploads(Request $request){
return [$request->file('file')];
return $this->uploadFiles($request,108,'props_and_set');
}
Use $request->hasFile('file') to see if the backend is able to get the file from the front end and then call the storage methods on the file.
I am trying to post a file (will be of type pdf or image), uploaded by the user in a form. The file will be taken by an AngularJS directive set 'onChange', sent through 'myPostr' function which is supposed to post my file to 'api/' so it can be received by PHP. Atm, PHP echoes empty arrays, atleast having the headers - 200 OK.
This my HTML:
<input name="file" class="form-control-file" my-directive type="file" accept="application/pdf">
This my simplified AngularJS script:
application.directive('myDirective', function(myPostr){
return{
restrict: 'A',
scope: true,
link: function(scope, element){
element.bind('change', function(){
if (element[0].files[0].type == 'application/pdf') {
var form = new FormData();
form.append('form', element[0].files[0])
myPostr(form, function(callback){
console.log(callback);
}) //or imagetype to be implemented
application.factory('myPostr', function($http){
return function (data, callback) {
$http.post('api/', {
data: data,
headers: {'Content-type':undefined}
})}
});
'myPoster' works fine for json data (form variables)
This are the multiple ways I've tried in PHP to display the received data:
//isset($_FILES['file']) returns false
$response = json_decode(file_get_contents('php://input'),true);
header('Content-Type: application/json');
echo json_encode($response); //or
//echo json_encode($_FILES);
All return this in the network console
Extra info: these are the console logs of the uploaded files
I'm working with Angular. I've to upload multiple images on via an API (made/written in Laravel).
The following body is accepted by the api
portfolio_id: 2
portfolio_image: [ {file1}, {file2} ] //Accepts in this format. File Objects in an array
My angular code is:
HTML
<div class="col-lg-12">
<label class="file-upload-label">Upload Profile Picture</label>
<input multiple (change)="fileSelected($event)" type="file" id="file" name="profile_pic"/>
<label for="file" class="btn-2">Upload</label>
</div>
Component.ts
selectedFile;
fileSelected(event) {
console.log(event);
this.selectedFile = <File>event.target.files;
console.log("Selected Files are:",this.selectedFile)
}
On button submit I'm running the following function from component.ts file:
portfolioImage(){
const formData = new FormData();
formData.append("portfolio_id", this.portfolioId);
formData.append("portfolio_image", this.selectedFile)
this.httpClient.post(this.URL, formData, httpOptionsMulti).subscribe(res => {
console.log(res);
alert('Files uploaded Successfully!');
})
}
Console Output: On file selection change event I see the following in console.log
FileList [ File, File ]
Upon expanding the array I see the following:
FileList(2)
0: File { name: "1.jpg", lastModified: 1578490559152, size: 317383, … }
1: File { name: "2.jpg", lastModified: 1578490599778, size: 288174, … }
length: 2
Issue:
Up on submission I see nothing in params on the network tab although I do get a images uploaded successfully message.
Things I've tried
I tried to upload via loop and changed the fileSelected(event) function to:
myFiles:string [] = [];
fileSelected(event) {
for (var i = 0; i < event.target.files.length; i++) {
this.myFiles.push(event.target.files[i]);
}
}
and upload function to:
portfolioImage(){
console.log("myfile",this.myFiles);
const formData = new FormData();
formData.append("portfolio_id", this.portfolioId);
for(var i = 0; i < this.myFiles.length; i++) {
formData.append("portfolio_image", this.myFiles[i]);
}
this.httpClient.post(this.URL, formData, httpOptionsMulti).subscribe(res => {
console.log(res);
alert('Files uploaded Successfully!');
})
}
But still no luck.
Summary: How to upload multiple files using angular on frontend and laravel api on backend. The laravel api accepts the files as objects in array: [ {file}, {file} ].
Any help will be highly appreciated. Thank you.
You did a little mistake in your upload function, consider the given
portfolioImage(){
const formData = new FormData();
formData.append("portfolio_id", this.portfolioId);
for(var i = 0; i < this.myFiles.length; i++) {
formData.append("portfolio_image[]", this.myFiles[i]);
}
this.httpClient.post(this.URL, formData, httpOptionsMulti).subscribe(res => {
console.log(res);
alert('Files uploaded Successfully!');
})
}
The portfolio_image should be used as given to make it multiple file array in formData. from your Laravel controller function, use as given to check uploaded temp files.
public function uploader(Request $request){
$data = [
$request->allFiles(),
];
return response()->json($data);
}
I'm working on a Laravel Spark project and I am trying to get a form to upload a folder to my S3 bucket. I have the form built:
<form enctype="multipart/form-data">
<input type="file" name="resume" v-model="form.resume">
<button #click="updateProfile">Update Profile</button>
</form>
Then I have a vue component set up to handle the form submit:
Vue.component('resume-links', {
template: '#edit-resume-links',
data() {
return {
form: new SparkForm({
resume: ''
})
};
},
methods: {
updateProfile() {
console.log(this.form.resume);
Spark.post('/route/to/controller', this.form).then(response => {
console.log(response);
});
}
}
});
Then in my laravel controller:
$resume = $request->file('resume');
$resumeFileName = time() . '.' . $resume->getClientOriginalExtension();
$s3 = \Storage::disk('s3');
$filePath = '/resumes/' . $resumeFileName;
$s3->put($filePath, file_get_contents($resume), 'public');
When I try to submit the form with a file it throws this error:
Call to a member function getClientOriginalExtension() on null
I have tried var_dumping $resume right after setting it to the file() and what I see outputted to the console is a bunch of js looking code
From everything that I reading it looks like file uploads with Laravel is super easy and I don't know why I am having this issue. Any assistance/advice would be appreciated! Thanks!
First of all, your file input needs to have the v-el attribute rather than v-model.
In your case it would be <input type="file" name="form" v-el:resume />.
Next, in your Vue component, you need to gather the FormData so that it becomes possible to send the file to the server. Files have to be handled slightly differently to plain text fields and such.
Add this to your methods object:
gatherFormData() {
const data = new FormData();
data.append('resume', this.$els.resume.files[0]);
return data;
}
In your updateProfile method you now need to send this data off to the server as a POST request.
updateProfile(e) {
e.preventDefault();
var self = this;
this.form.startProcessing();
$.ajax({
url: '/route/to/controller',
data: this.gatherFormData(),
cache: false,
contentType: false,
processData: false,
type: 'POST',
headers: {
'X-XSRF-TOKEN': Cookies.get('XSRF-TOKEN')
},
success: function (response) {
self.form.finishProcessing();
console.log(response)
},
error: function (error) {
self.form.setErrors(error.responseJSON);
}
});
},
Finally, in your controller method, you can now handle the file as normal
(e.g., $request->file('resume');)
Handling files with Laravel really is a breeze – you just need to make sure you're actually getting them to the server ;)
First of all I'd like to ask that you don't suggest I turn to a jQuery plugin to solve my issue. I'm just not willing to make my app work with a plugin (and it prevents me from learning!)
I have a form with a bunch of fields that I'm passing to my backend via the use of jQuery's $.post() This is what I have as my jQuery function:
$.post(
"/item/edit",
$("#form").serialize(),
function(responseJSON) {
console.log(responseJSON);
},
"html"
);
This is how I opened my form:
<form action="http://localhost/item/edit" method="post" accept-charset="utf-8" class="form-horizontal" enctype="multipart/form-data">
This was auto generated by codeigniter's form_open() method (hence why action="" has a value. Though this shouldn't matter because I don't have a submit button at the end of the form)
Within my #form I have this as my file input: <input type="file" name="pImage" />
When the appropriate button is hit and the $.post() method is called, I have my backend just print the variables like so: print_r($_POST) and within the printed variables the 'pImage' element is missing. I thought that maybe files wouldn't come up as an element in the array so I went ahead and just tried to upload the file using this codeigniter function: $this->upload->do_upload('pImage'); and I get an error: "You did not select a file to upload."
Any idea as to how I can overcome this problem?
You cannot post an image using AJAX, i had to find out here as well PHP jQuery .ajax() file upload server side understanding
Your best bet is to mimic an ajax call using a hidden iframe, the form has to have enctype set to multipart/formdata
Files wont be sent to server side using AJAX
One of the best and simplest JQuery Ajax uploaders from PHP LETTER
all you need is include js in your header normally and Jquery code will be like below
$.ajaxFileUpload({
url:'http://localhost/speedncruise/index.php/snc/upload/do_upload',
secureuri:false,
fileElementId:'file_upload',
dataType: 'json',
data : {
'user_email' : $('#email').val()
},
success: function (data, status) {
// alert(status);
// $('#avatar_img').attr('src','data');
}
,
error: function (data, status, e) {
console.log(e);
}
});
wish this can help you
I can't do this with codeigniter and Ajax, I pass the image to base64 and in the controller I convert into a file again
//the input file type
<input id="imagen" name="imagen" class="tooltip" type="file" value="<?php if(isset($imagen)) echo $imagen; ?>">
//the js
$(document).on('change', '#imagen', function(event) {
readImage(this);
});
function readImage(input) {
var resultado='';
if ( input.files && input.files[0] ) {
var FR= new FileReader();
FR.onload = function(e) {
//console.log(e.target.result);
subirImagen(e.target.result);
};
FR.readAsDataURL( input.files[0] );
}
}
function subirImagen(base64){
console.log('inicia subir imagen');
$.ajax({
url: 'controller/sube_imagen',
type: 'POST',
data: {
imagen: base64,
}
})
.done(function(d) {
console.log(d);
})
.fail(function(f) {
console.log(f);
})
.always(function(a) {
console.log("complete");
});
}
//and the part of de controller
public function sube_imagen(){
$imagen=$this->input->post('imagen');
list($extension,$imagen)=explode(';',$imagen);
list(,$extension)=explode('/', $extension);
list(,$imagen)=explode(',', $imagen);
$imagen = base64_decode($imagen);
$archivo='archivo.'.$extension;
file_put_contents('imagenes/'.$archivo, $imagen);
chmod('imagenes/'.$archivo, 0777); //I use Linux and the permissions are another theme
echo $archivo; //or you can make another thing
}
ps.: sorry for my english n_nU