[solved] QUploader: Using the abort button with upload factory
-
Because I need to upload a file with some additional JSON pieces as multipart/formdata, I am using the upload factory of the QUploader. However, this seems to disable a lot of the niceties of the uploader. For example
-
Biggest issue: the X button to abort a download no longer is available, the entire thing is greyed out when factory is running. See image. I would like the user to be able to cancel still.
-
The progress part (30% of 5MB or whatever) also is totally disabled.
-
When the file is successfully uploaded, the QUploader just clears as if it never uploaded anything. I thought maybe this is becauase I have resolve(null), but when I put resolve(file) as I’d expect to, it does the same thing plus throws the error that q-uploader has an invalid :url.
I don’t see a way I can use the basic functionality and send a multipart/form-data with a file and some json, so I think i have to use the factory. Does it mean I have to live with a super weak version of the QUploader? Is there a way to add my json in without the factory and just use :url=. ?
Here is my code:
template part:
<q-uploader id="fileUploader" ref="fileUploader" color="secondary" text-color="white" bordered flat no-thumbnails max-files=1 :factory="uploadFile" @added="addFile" @uploaded="uploadSuccess" @failed="uploadFail" label="Excel and CSV Files Supported" accept=" .xlsx, .xls, .csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/csv" ></q-uploader>
methods:
methods: { addFile(file) { // eslint-disable-next-line prefer-destructuring this.selectedFile = file[0]; }, uploadFile() { return new Promise((resolve, reject) => { const uploader = this.$refs.fileUploader; const file = this.selectedFile; const formData = new FormData(); const uploadDetails = JSON.stringify( { clientId: 2, userId: 1, fileName: file.name, effectiveDate: '01-01-2020', }, ); // attach the json part of the post body formData.append( 'uploadDetails', new Blob([uploadDetails], { type: 'application/json' }), ); // attach the file to the post body formData.append('file', file); // set headers const config = { headers: { 'Content-Type': 'multipart/form-data', }, }; // build api url const uploadApi = `http://${process.env.FILE_UPLOAD_API}/v1/uploadData`; // do it axios.post( uploadApi, formData, { headers: { config, }, }, ).then(() => { uploader.removeFile(file); this.uploadSuccess(); resolve(null); }) .catch(() => { // if needed you can add catch((err) to get the msg this.uploadFail(); reject(); }); }); }, uploadSuccess() { this.$emit('fileUploaded', true); }, uploadFail() { dialog('Upload Failure', 'The file upload failed. Check your connection and try again. ', this.$q); this.$emit('fileUploaded', false); },
-
-
I was able to resolve this issue myself by using some of the props. Instead of using the factory, I just used the following to force the request to look how my back end wanted. Posting this to help future users:
template:
<q-uploader id="fileUploader" ref="fileUploader" color="secondary" text-color="white" bordered flat no-thumbnails max-files=1 :url="uploadApi" :form-fields="generateFileData" :field-name="(name) => 'file'" @added="addFile" @uploaded="uploadSuccess" @failed="uploadFail" label="Excel and CSV Files Supported" accept=" .xlsx, .xls, .csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/csv" ></q-uploader> </div>
Methods:
generateFileData() { // TODO: Set client/user and effective dates const uploadDetails = JSON.stringify( { clientId: 2, userId: 1, fileName: 'aFileName', effectiveDate: '01-01-2020', }, ); const blobDetails = new Blob([uploadDetails], { type: 'application/json' }); // attach the json part of the post body return [{ name: 'uploadLocationProviderDetails', value: blobDetails, }]; },
The trick was the field-name and form-fields props of the uploader mixed with that little blog trick to make it json content in the method