websanova/vue-upload

Nuxt Compatability

Opened this issue · 5 comments

Is there a way to implement this into nuxt?

I was under the impression anything made for Vue can work in Nuxt if you know how to create the proper plugin.
I created a simple vue-upload.js plugin like so:

import Vue from 'vue'
import VueUpload from '@websanova/vue-upload'

Vue.use(VueUpload)

Added the config to the nuxt.config.js and I get no errors until I attempt to upload a file.

Cannot read property 'post' of undefined

I tried various file sizes, some fail so its a sign its actually working.
To the point where if the files is valid and the error for post comes about.

Looks to be this bit of code in upload.js causing the problem

function __http(data) {
        __upload.Vue
            .http
            .post(data.url, data.body, {progress: data.progress})
            .then(data.success, data.error);
    }

I assume because its using default Vue http post request where most nuxt and vue apps use axios and don't bother with vue-resource

Just curious. This component looks very promising and exactly what I need. Just my project is in Nuxt requiring SSR.

Thanks,

DAve

Hey Dave,

Yes, so ya, you can override the http method there as by default it's for vue-resource.

Just needs the axios or whatever version and should work then.

By the way if you are using axios and get it working would be great if you could share the code snippet and I can add it to the docs or maybe even just put it in the code directly of it's small enough.

No problem. I plan to make it axios / nuxt friendly over the weekend and will share when finished.
I'm no JS coder but I am sure I can figure it out.

I figure from what I did see it appears the http request is just in that one spot.
Could be wrong but if thats the only one place it would save me from wondering.

Keep you posted.

Dave

Yes, it's just that one _http method which by default is the vue-resource http plugin.

Just need to override that one method with however axios does it.

Just thought I'd share in case it might help out others, this is a stripped down version of how i made it work in a component in an Nuxt application. In this case the application will return an error message as a Message attribute, but this might have to be changed depending on how your backend is set up:

<template lang="pug">
	div
		div
			button(v-bind:id="uiqueId" @click="$upload.select(uiqueId)" v-bind:disabled="$upload.meta(uiqueId).state === 'sending'") Drag and drop or press to upload
		div(v-if="$upload.files(uiqueId).progress.length")
			progress(max="100" v-bind:value="$upload.meta(uiqueId).percentComplete")
			div {{ $upload.meta(uiqueId).percentComplete }}% Complete
		div(v-if="!$upload.files(uiqueId).all.length") No uploads here yet.

		h2(v-if="$upload.files(uiqueId).progress.length") Progress
		div(v-for="file in $upload.files(uiqueId).progress")
			div {{ file.name }}
			progress(max="100" v-bind:value="file.percentComplete")
			div {{ file.percentComplete }}% Complete

		h2(v-if="$upload.files(uiqueId).queue.length") Queue
		div(v-for="file in $upload.files(uiqueId).queue")
			div {{ file.name }}
			div Queued for upload

		h2(v-if="$upload.files(uiqueId).success.length") Success
		div(v-for="file in $upload.files(uiqueId).success")
			div {{ file.name }}
			div Uploaded successfully.

		h2(v-if="$upload.files(uiqueId).error.length") Error
		div(v-for="file in $upload.files(uiqueId).error")
			div {{ file.name }}
			div {{ file.error[0].code }} {{ file.error[0].msg }}
</template>
<script>
import Vue from 'vue'
import VueUpload from '@websanova/vue-upload'

export default {
	name: 'file-upload',
	props: {
		uploadUrl: {
			type: String,
			required: true
		}
	},
	computed: {
		uiqueId() {
			return `file-upload-dropzone_${this._uid}`
		}
	},
	created() {
		Vue.use(VueUpload, {
			http: (data) => this.$axios.$post(data.url, data.body).then(data.success).catch(data.error),
			parseErrors: (error) => [{code: error.response.status, msg: (error.response.data != null && error.response.data.Message || error.response.statusText)}]
			}
		})
	},
	mounted() {
		this.$upload.on(this.uiqueId, {
			maxFilesSelect: 20,
			dropzoneId: this.uiqueId,
			multiple: true,
			url: this.uploadUrl,
			onStart() {},
			onSuccess(file, serverResponse) {},
			onError(error) {},
			onEnd() {}
		})
	},
	beforeDestroy() {
		this.$upload.off(this.uiqueId)
	}
}
</script>

Edit: Added server response to onSuccess callback function

For Nuxt example:
If the page is refreshed / F5 you get errors of undefined meta / files. Regualr navigation works but if you F5 the page with the upload component I get errors.