I have a file upload component that I am trying to pass in data with the image to the controller so I can create the photo object. Some of the data are things such as disk, like 'S3' so the controller will know where to store the image. However, FilePond doesn't seem to allow any variables, props or vuex state to be passed into the FilePond instance. No matter how I try it, it always says it is always undefined. in FilePond, it says you can use formData.append('Hello', 'World')
FilePond.setOptions({
server: {
url: 'http://192.168.0.100',
timeout: 7000,
process: {
url: './process',
method: 'POST',
headers: {
'x-customheader': 'Hello World',
},
withCredentials: false,
onload: (response) => response.key,
onerror: (response) => response.data,
ondata: (formData) => {
formData.append('Hello', 'World');
return formData;
},
},
revert: './revert',
restore: './restore/',
load: './load/',
fetch: './fetch/',
},
});
but if you sub 'world' for
this.photo.disk, or
state.photoUploader.photo.disk, or
this.$store.state.photoUploader.photo.disk or mapState and use
photo
or anything it is always undefined. It doesn't know what is outside of this filepond instance.
There is also the fileMetaDataObject you can pass. This also has the same issue. I can pass in strings all day and it works, but as soon as you try to pass in a variable of any kind it has no idea what it is. https://pqina.nl/filepond/docs/api/plugins/file-metadata/
FilePond.setOptions({
fileMetadataObject: {
hello: 'world',
},
});
I tried just the origin metaData option
metadata: {
date: '2018-10-5T12:00',
},
All of the variables I mentioned show their values in console.log and when showing it in the component, but will not work in the filepond instance. I need to be able to send data with the photo to the controller to create the photo object.
Here is an example of my component (FYI, I put all different type of variables as examples of what I have tried):
<template>
<div>
<Head title="Photo Uploader" />
<Card
class="flex flex-col items-center justify-center h-full"
>
<!-- Photo Fields -->
<div class="flex flex-col w-full pb-1 pt-8">
<div class="flex flex-row w-full">
<div class="pr-4">
<validation-check :validated="photoFieldsExists"></validation-check>
</div>
<div class="flex flex-col">
<heading class="pb-2">Step 5: Upload Images: </heading>
<h1>Click to choose images, or drag and drop into box.</h1>
<h1 class="mb-6">{{ photo }}</h1>
</div>
</div>
<div class="w-full h-full">
<file-pond
name="image"
ref="pond"
label-idle="Click to choose images, or drag here..."
@init="handleFilePondInit"
accepted-file-types="image/*"
/>
</div>
</div>
</Card>
</div>
</template>
<script>
import ApiUrls from "../../components/mixins/ApiUrls";
import ValidationCheck from './ValidationCheck';
import {mapState} from 'vuex';
// Import FilePond
import vueFilePond, { setOptions } from 'vue-filepond';
// Import plugins
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type/dist/filepond-plugin-file-validate-type.esm.js';
import FilePondPluginFileMetadata from 'filepond-plugin-file-metadata';
// import FilePondPluginImagePreview from 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.esm.js';
// Import styles
import 'filepond/dist/filepond.min.css';
// import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
setOptions({
server: {
process: {
url: Nova.config('apiUrl') + '/photos',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
},
ondata: (formData) => {
formData.append('photo_group_id', this.photoGroupId);
formData.append('photo_type_id', this.photoTypeId);
formData.append('disk', this.photo.disk);
formData.append('title', this.photo.title);
formData.append('alt', this.photo.alt);
formData.append('description', this.photo.description);
formData.append('src', this.photo.src);
formData.append('sub_folder', this.photo.subFolder);
return formData;
},
}
},
fileMetadataObject: {
photo_group_id: "photo.photo_group_id",
photo_type_id: "this.$store.state.photoUploader.photoTypeId",
disk: "photo.disk",
title: "this.photo.title",
alt: "state.photoUploader.photo.alt",
description: "",
src: "",
sub_folder: "",
},
});
const FilePond = vueFilePond(
FilePondPluginFileValidateType,
FilePondPluginFileMetadata
);
export default {
components: {
ValidationCheck,
FilePond
},
mixins: [ApiUrls],
props: ["photo"],
computed: {
// TODO: Change setOptions to pull from computed properties
...mapState({
photo: state => state.photoUploader.photo,
photoTypeId: state => state.photoUploader.photoTypeId,
photoGroupId: state => state.photoUploader.photoGroupId
})
},
data() {
return {
includesPhotos: '?include=photos',
metaData: {
photo_group_id: this.$store.state.photoUploader.photoGroupId,
photo_type_id: this.$store.state.photoUploader.photoTypeId,
disk: this.$store.state.photoUploader.photo.disk,
title: this.$store.state.photoUploader.photo.title,
alt: this.$store.state.photoUploader.photo.alt,
description: this.$store.state.photoUploader.photo.description,
src: this.$store.state.photoUploader.photo.src,
sub_folder: this.$store.state.photoUploader.photo.subFolder
},
// photo: this.photo,
// photoGroupId: this.photoGroupId,
// photoTypeId: this.photoTypeId,
}
},
mounted() {
this.fetchData();
},
methods: {
fetchData() {
console.log('fetch data in upload handler');
console.log('Photo: ');
console.log(this.$store.state.photoUploader.photo);
console.log('PhotoTypeId: ');
console.log(this.$store.state.photoUploader.photoTypeId);
},
handleFilePondInit: function () {
console.log('FilePond has initialized');
console.log('FilePond Object: ', this.$refs.pond)
// example of instance method call on pond reference
this.$refs.pond.getFiles();
console.log('handle file pond 1:')
console.log(this.$refs.pond.getFiles());
// console.log('this.state.files: ');
// console.log(this.state.files);
},
}
}
</script>
<style>
/* Scoped Styles */
</style>
I have also tried passing it into fileponds custom server option, but with no luck. Here is their example of that:
FilePond.setOptions({
server: {
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
// fieldName is the name of the input field
// file is the actual file object to send
const formData = new FormData();
formData.append(fieldName, file, file.name);
const request = new XMLHttpRequest();
request.open('POST', 'url-to-api');
// Should call the progress method to update the progress to 100% before calling load
// Setting computable to false switches the loading indicator to infinite mode
request.upload.onprogress = (e) => {
progress(e.lengthComputable, e.loaded, e.total);
};
// Should call the load method when done and pass the returned server file id
// this server file id is then used later on when reverting or restoring a file
// so your server knows which file to return without exposing that info to the client
request.onload = function () {
if (request.status >= 200 && request.status < 300) {
// the load method accepts either a string (id) or an object
load(request.responseText);
} else {
// Can call the error method if something is wrong, should exit after
error('oh no');
}
};
request.send(formData);
// Should expose an abort method so the request can be cancelled
return {
abort: () => {
// This function is entered if the user has tapped the cancel button
request.abort();
// Let FilePond know the request has been cancelled
abort();
},
};
},
},
});
I was facing with this problem, you need to use the advice contained in this thread.
https://github.com/pqina/vue-filepond/issues/99
FilePond has a lot of Methods and Events, why you are trying to add something directly in server settings options? You've complicated your logic unnecessarily.