Can someone help me on how to upload a file on pouchdb and display those uploaded files on page. I want to upload a file including name info of that file. When I check the fetch files using the console I can see [object object]. Am I doing the right thing? Any advice is well appreciated. Here is my code.
//Notes.vue
// By the way Im using onsen ui for this
<template>
<v-ons-page>
<v-ons-list>
<v-ons-list-header>Auditing</v-ons-list-header>
<v-ons-list-item v-for="note in notes">
<div class="left">
<img src="" alt="">
</div>
<div class="center">
<span>{{ note._attachment['files'].data }} File here</span>
</div>
</v-ons-list-item>
</v-ons-list>
// Customize form for uploading file and info
<v-ons-alert-dialog
modifier="rowfooter"
:visible.sync="dialogVisible"
>
<span slot="title">Create a Note</span>
//File name of the file
<v-ons-input float
placeholder="Name of note"
v-model="name"
>
</v-ons-input>
// File
<v-ons-input type="file" #change="onFileChange"></v-ons-input>
<v-ons-button #click="addNotes(name)">Submit</v-ons-button>
</v-ons-alert-dialog>
</v-ons-page>
</template>
//Here the methods for uploading and reading file uploaded
<script>
import PouchDB from 'pouchdb'
var db = new PouchDB('reviewerdb')
export default {
data() {
return {
dialogVisible: false,
notes: [],
file: '',
name: '',
path
}
},
mounted() {
this.getNotes();
print('notes: ' + this.notes);
},
//Methods just adding a desciption
methods: {
onFileChange(event) {
this.file = event.target.files[0];
},
addNotes() {
db.put({
_id: 'notes',
_attachments: {
"file": {
type: this.file.type,
data: this.file
}
}
})
},
getNotes() {
db.get('notes', {attachments:true}).then(function (note) {
this.notes = note;
});
}
}
}
Related
I have a module that has add and edit form. In the add and edit form, the user can upload files. When edit, it will show uploaded files
In add form, it works. When user upload, file size of file displays file size correctly
But my problem is when edit form, each file displays 1kb file size on all files
You can see the problem here:
I use filepond package to upload files
My vue component like this :
<template>
<b-card>
<b-form #submit="onSubmit">
<b-row>
<b-col cols="8">
...
<b-form-group
id="fieldset-horizontal"
label-cols-sm="4"
label-cols-lg="2"
content-cols-sm
content-cols-lg="8"
label-for="description"
>
<template v-slot:label>
Description
</template>
<b-form-input id="description" v-model="description" required maxlength="100"></b-form-input>
</b-form-group>
<b-form-group
id="fieldset-horizontal"
label-cols-sm="4"
label-cols-lg="2"
content-cols-sm
content-cols-lg="9"
label-for="files"
>
<template v-slot:label>
Files
</template>
<file-pond v-if="this.$route.params.id"
label-idle='Drag and drop files here... or <span class="filepond--label-action"> Browse </span>'
v-bind:allow-multiple="true"
v-bind:server="server"
v-bind:files="files"
/>
<file-pond v-else
label-idle='Drag and drop files here... or <span class="filepond--label-action"> Browse </span>'
v-bind:allow-multiple="true"
accepted-file-types='application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, .xlsx'
v-bind:server="server"
v-bind:required="true"
/>
</b-form-group>
</b-col>
<b-col cols="4">
<b-button type="submit" #click="save" variant="success">Save</b-button>
</b-col>
</b-row>
</b-form>
</b-card>
</template>
<script>
import { mapGetters, mapActions } from "vuex"
import vueFilePond from "vue-filepond"
...
export default {
data() {
return {
files: [],
server: {
process: (fieldName, file, metadata, load, error, progress, abort) => {
if(file.lastModified) {
if (this.dataFiles.findIndex(a => a.fileName == file.name) > -1) {
error(new Error('More than one file with the same name cannot be attached'));
}
else {
const data = new FormData()
data.append('files[]', file)
const CancelToken = axios.CancelToken
const source = CancelToken.source()
const config = {
method: 'post',
url: `${apiUrl}/upload`,
data : data,
cancelToken: source.token,
onUploadProgress: (e) => {
progress(e.lengthComputable, e.loaded, e.total)
},
}
axios(config)
.then(response => {
this.setSaveFile({
id: response.data.id,
name: response.data.name,
url: response.data.url,
})
load(response.data.id)
})
.catch((thrown) => {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message)
} else {
error('error')
}
})
return {
abort: () => {
source.cancel('Operation canceled by the user.')
}
}
}
}
else { /* this will show data file when edit data */
this.setSaveFile({
id: metadata.id,
name: metadata.name,
url: metadata.url,
})
load(metadata.id)
}
},
revert: (uniqueFileId, load, error) => {
const type = this.$route.params.id ? 'edit' : 'add'
this.setDeleteFile({id: uniqueFileId, type: type } )
error('error')
load()
},
},
}
},
async mounted() {
if(this.$route.params.id) {
await this.setEdit(this.$route.params.id)
}
},
computed: {
...mapGetters([
"dataFiles",
"dataEditSuccess",
])
},
watch: {
dataEditSuccess: {
handler(data) {
if (this.$route.params.id && data) {
this.showEditData()
}
},
immediate: true
}
},
methods: {
...mapActions([
"setSaveFile",
"setDeleteFile",
"setEdit",
]),
showEditData() {
const data = this.dataEditSuccess
this.description = data.description
for (let key in data.files) {
let filePost = {
source: data.files[key].name,
options: {
metadata: {
id: data.files[key].id,
name: data.files[key].name,
url: data.files[key].url,
},
},
}
this.files.push(filePost)
}
},
},
...
}
</script>
How can I solve this problem?
Note :
The docs : https://github.com/pqina/vue-filepond
Update :
I make my code in codesandbox like this : https://codesandbox.io/s/vue-filepond-live-demo-forked-0v3r3j
Here it looks the same file size
Actually I can uncomment this script to solve my problem :
file: {
name: this.filesFromApi[key].name,
size: this.filesFromApi[key].size,
},
But it makes me unable to fetch metadata in process. So process cannot be called. You can try it and see in the console log
If you're fetching some initial file metadata from an API, couldn't you add that data to vuex at mount time instead of trying to do it through filepond which would give you back the same metadata anyways? Regardless, perhaps listening to one of these events can help you.
in your component:
methods: {
onProcessFile(error, file) {
console.log('processed file metadata', file.getMetadata())
},
onAddFile(error, file) {
console.log('added file metadata', file.getMetadata())
}
},
<file-pond
name="test"
ref="pond"
#processfile="onProcessFile"
#addfile="onAddFile"
label-idle="Drop files here or <span class='filepond--label-action'>Browse</span>"
allow-multiple="true"
v-bind:files="myFiles"
v-bind:server="myServer"
/>
i'm trying to make work Laravue Dropzone, but I have'nt working yet
Here is the code:
<el-dialog :title="'Importar Bitacora'" :visible.sync="dialogFormVisible">
<div v-loading="weblogCreating" class="form-container">
<el-form ref="weblogForm" :rules="rules" :model="newBitacora" label-position="left" label-width="150px">
<div class="editor-container">
<dropzone id="CargarBitacora" url="/api/bitacora/importar" #dropzone-removedFile="dropzoneR(e)" #dropzone-error="dropzoneError" #dropzone-success="dropzoneS" />
</div>
</el-form>
</div>
<div slot="footer" class="dialog-footer">
<el-button #click="dialogFormVisible = false">
{{ $t('bitacora.cancel') }}
</el-button>
<el-button type="primary" #click="handleUpload()">
{{ $t('bitacora.confirm') }}
</el-button>
</div>
</el-dialog>
<script>
import Dropzone from '#/components/Dropzone';
export default {
name: 'BitacoraList',
components: { Dropzone },
data() {
return {
files: [],
},
created() {
.. code here ..
},
methods: {
handleUpload(e) {
const formData = new FormData();
this.files.forEach(file => {
formData.append('files[]', file);
});
console.log(this.files);
},
}
};
</script>
I've tried to pass the files to handleUpload, but I can't make it work to the moment
I figured out how to upload files with dropzone, en the method handleUpload I just have to send the file to a post method in laravel backend who upload a temporary file
dropzoneR(file) {
var name = file.upload.filename;
fileResource.borrar(name).then(response => {
this.files.splice(this.files.indexOf(name), 1);
if (this.files.length < 1) {
this.btnUpload = true;
}
}).catch(error => {
console.log(error);
});
},
and returns an ok if it gets uploaded, then when I confirm thats the files I need up, other method in laravel backend who do what a want to do with the file if its an excel file (in mi case) upload the data to the database, or what ever I want. like this
async handleUpload(e) {
this.weblogCreating = true;
await bitacoraResource.store(this.files).then(response => {
this.$message({ message: 'Bitacoras importadas satisfactoriamente', type: 'success' });
this.files = '';
this.dialogImportVisible = false;
this.weblogCreating = false;
this.getList();
}).catch(error => {
this.$message({
message: 'Error importando las bitacoras ' + error.getMessage,
type: 'error',
});
this.weblogCreating = false;
console.log(error.message);
});
},
I'm working on a VueJS Application and I'm using net core as backend,
I have a component with an upload function that is working but not as expected, for example, if i chose to upload 3 files it would upload just the first out of 3.
My HTML
<div class="container">
<div class="large-12 medium-12 small-12 cell">
<label>
Files
<input type="file" name="file" ref="files" multiple v-on:change="fileChange($event.target.files)" />
</label>
<v-btn outline color="primary" dark v-on:click="upload()">Submit</v-btn>
</div>
</div>
Part of my script
export default {
name: 'Profile',
data() {
return {
records: [],
application: [],
profile: [],
history: [],
userValues: [],
dialog: false,
notifications: false,
sound: true,
widgets: false,
files: new FormData()
};
},
methods: {
});
}
And my Controller
[Produces("application/json")]
[Route("api/[controller]")]
public class UploadController : Controller
{
private IHostingEnvironment _hostingEnvironment;
public UploadController(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
{
file.CopyTo(stream);
}
}
return Json("Upload Successful.");
}
catch (System.Exception ex)
{
return Json("Upload Failed: " + ex.Message);
}
}
}
Also along with the files, I would like to pass email: this.profile.email as a parameter from my vue.
Like I said it is working but just one file at the time.
var file = Request.Form.Files[0]; That will pop off only the first file from your request. Instead, you need to check for
Instead access your files in a loop:
foreach(uploadedFile in Request.Form.Files) {
}
I am using vue and element ui to upload files. But I don't know how to get upload files url (basically I want to check the file type - jpg or pdf and then do something).
<div id="app">
<el-upload action="https://jsonplaceholder.typicode.com/posts/" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove">
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<embed width="100%" :src="dialogImageUrl">
</el-dialog>
<p>file type: "{{ checkType() }}"</p>
</div>
var Main = {
data() {
return {
dialogImageUrl: '',
dialogVisible: false
};
},
methods: {
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
checkType(){
var filename = this.dialogImageUrl;
return filename.split('.').pop();
}
}
}
Please Help...
I have add this try to get URL..but it doesn't work..
var filename = document.getElementsByTagName("embed")[0].src;
console.log(filename);
you can use :before-upload attribute of el-upload. please take look of changed code.
<div id="app">
<el-upload action="https://jsonplaceholder.typicode.com/posts/" **:before-upload="checkType"** list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove">
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<embed width="100%" :src="dialogImageUrl">
</el-dialog>
<p>file type: "{{ checkType() }}"</p>
</div>
var Main = {
data() {
return {
dialogImageUrl: '',
dialogVisible: false
};
},
methods: {
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
**checkType(file){**
console.log(file.type);
// do your action here based on file.type
var filename = this.dialogImageUrl;
return filename.split('.').pop();
}
}
}
On my website you can upload a dog with attributes and images.
Vuejs is the frontend and Laravel the backend.
I am using this vue-dropzone component in my project to upload images.
The problem
I want to upload the images and the attributes of a dog at the same time (when the user clicks the submit button), so that the image files can be linked to the dog's id in the database.
Laravel function to register a new dog (route: 'api/dogs')
public function store(Request $request)
{
$attributes = [
'name' => $request->input('name'),
'type' => $request->input('dogType'),
...
];
$dogId = Dog::insertGetId($attributes);
// Upload files
if ($request->hasFile('files')) {
// getting all files
$files = $request->file('files');
// Count files to be uploaded
$file_count = count($files);
// start count how many uploaded
$uploadcount = 0;
if($uploadcount == $file_count) {
return true;
} else {
FileController::store($request, 0, 0, $dogId, $files, $uploadcount);
}
}
return $dogId;
}
Dropzone component (Formdropzone)
<template>
<div>
<dropzone
:id="this.id"
:url="this.url"
:accepted-file-types='"image/*"'
:use-font-awesome="true"
:preview-template="template"
:auto-process-queue="false" <----
:upload-multiple="true"
:parallel-uploads=100
:max-files=100
#vdropzone-success="showSuccess"
>
</dropzone>
</div>
</template>
<script>
import Dropzone from 'vue2-dropzone'
export default {
props: {
id: {
type: String,
required: true
},
url: {
type: String,
required: true
}
},
components: {
Dropzone
},
methods: {
showSuccess(file) {
console.log('A file was successfully uploaded')
},
template() {
return `
<div class="dz-preview dz-file-preview">
<div class="dz-image" style="width: 200px;height: 200px">
<img data-dz-thumbnail /></div>
<div class="dz-details">
<div class="dz-size"><span data-dz-size></span></div>
<div class="dz-filename"><span data-dz-name></span></div>
</div>
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
<div class="dz-error-message"><span data-dz-errormessage></span></div>
<div class="dz-success-mark"><i class="fa fa-check"></i></div>
<div class="dz-error-mark"><i class="fa fa-close"></i></div>
</div>
`;
}
}
}
</script>
Register dog component
<tab-content title="Images">
<div class="form__input__wrapper">
<span class="label">Images (optional)</span>
<formdropzone url="http://domain.local/api/dogs" ref="dogDropzone" id="dogDropzone"></formdropzone>
</div>
</tab-content>
<script>
import Formdropzone from './Formdropzone'
export default {
data() {
return {
dog:{
name: '',
dogType: '',
...
}
}
},
methods: {
publish() {
this.$http.post('api/dogs', this.dog)
.then(response => {
this.$refs.dogDropzone.processQueue() <----
this.$router.push('/feed')
})
}
},
components: {
'formdropzone': Formdropzone
}
</script>
The error message
Uncaught (in promise) TypeError: Cannot read property 'processQueue' of undefined
I would be very thankful for any kind of help!