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);
}
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'm havong some trouble to upload multiple file at once in my vue and php app. I'm using slim to have an endpoint where upload request is posted:
On the server side I have this code to test if all works fine:
$app->post('/compress', function(Request $request, Response $response){
$files = $request->getUploadedFiles();
var_dump($files); // this will result in empty
//return $response;
});
In my javascript code, inside a vue method I have this code that is called when the file input will change:
let formData = new FormData();
for(let i; i < this.$refs.selectedImages.files.length; i++){
formData.append('images[]', this.$refs.selectedImages.files[i]);
}
let config = {
header: {
'Content-Type': 'multipart/form-data',
},
withCredentials: true
}
axios.post('http://localhost:3000/compress', formData, config)
.then( (response) => {
console.log(response, response.data);
});
tha result is that the var_dump will give me empty. How I can fix?
Can you try this one?
for( var i = 0; i < this.$refs.selectedImages.files.length; i++ ){
let file = this.$refs.selectedImages.files[i];
formData.append('images[' + i + ']', file);
}
After a lot of debug I've fixed the code. The problem was with the for() loop that seems not working to iterate FileList in my case. I've replaced it with a forEach() and voilà! The server started to get the uploaded files.
let files = this.$resf.selectedImages.files;
let formData = new FormData();
files.forEach( (el) => {
formData.append('images[]', el);
});
I got a problem with adding more files on updating products with existing files from the server using vueDropzone. In the first place, I don't have a problem with adding multiple files, but when I edit the product then add more files, or even just I only updated the Product Name without updating the files. It throws me an error from the Laravel validator.
By the way, I am using Vue.js and I am only using one method for Add/Update product.
Here is my vuedropzone component.
<vue-dropzone
ref="product_images"
id="dropzone"
:options="dropzoneOptions"
#vdropzone-success-multiple="dzAfterComplete"
#vdropzone-removed-file="dzAfterRemove"
#vdropzone-max-files-reached="dzMaxFiles"
#vdropzone-error-multiple="dzComplete"
#vdropzone-file-added-manually="dzThumbnil">
</vue-dropzone>
This is my submitProduct() method.
submitProduct() {
let images = this.$refs.product_images.getAcceptedFiles();
let formData = new FormData();
if ( images.length > 0 ) {
for ( var i = 0; i < images.length; i++ ) {
let file = images[i];
formData.append('images[' + i + ']', file);
}
}
else {
formData.append('images[]', '');
}
if (this.product.id)
formData.append('id', this.product.id); // update if it has ID
// axios.post()
}
And my editProduct method.
editProduct(data) {
this.$refs.product_images.removeAllFiles(); // empty dropzone first
for ( var i = 0; i < data.images.length; i++ ) {
let file = {
size: data.images[i].size,
name: data.images[i].name,
type: data.images[i].type,
accepted: true
};
let url = '{{ url('/') }}/' + data.images[i].path;
this.$refs.product_images.manuallyAddFile(file, url);
}
$('#productModal').modal('show');
},
The existing files are displayed on the dropzone area, however, when I submit the form the Laravel validator throws an error because the images are null. But it has files when I check in console.log() before submitting the form.
public function storeProduct(Request $request)
{
$this->validate($request, [
'images.*' => 'mimes:jpeg,jpg,png|required|max:2048',
]);
// when I check the file
return response()->json($request->file('images'));
// it's return images: null
}
Any help would be much appreciated. Hope it's a clear statement.
Cheers!
Hello friends I created a project in angular 4 I want to upload an image and sent request to the PHP file but form-data can't append values and images.
please help me
I include FormGroup, FormControl, FormBuilder, Validators, Http
const Image = this.com_Image.nativeElement;
if (Image.files && Image.files[0]) {
this.comImageFile = Image.files[0];
}
const ImageFile: File = this.comImageFile;
// [enter image description here][1]
let formData = new FormData();
formData.append('companyName', value.companyName);
formData.append('username', value.username);
formData.append('uploadFile', ImageFile, ImageFile.name);
console.log(formData);
Html
<input #fileSelect type="file" class="form-control" (change)="onFileChanged($event)" accept=".jpg, .png"/>
component
export class FileUploadComponent {
#ViewChild('fileSelect') fileSelectInput: ElementRef;
fileToUpload: any;
onFileChanged(event) {
// https://stackoverflow.com/questions/13602039/e-srcelement-is-undefined-in-firefox
this.fileToUpload = (event.srcElement || event.target).files;
let formData: FormData = new FormData();
formData.append('file', this.fileToUpload[0]);
this.createOrUpdateResource(formData);
}
// https://stackoverflow.com/questions/48059121/angular4-file-upload-put-request-fails,
so making this POST
private createOrUpdateResource(formData: FormData) {
this.http.post<any>(`http://localhost:8080/upload`, formData).subscribe((res) => {
//success
}, error => {
//error
});
}
}
Have you tried to pass only name and value for the image?
For file management (in general) this has worked for me:
formData.append('uploadFile', ImageFile);
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) {