How to upload a photo in my Form and into my Vuex store? - vue.js

I'm practicing building a Hybrid Mobile app with Quasar, Vue and Vuex.
I've successfully added my form input fields to my Vuex store but I don't know how to upload a file, in this case a photo, within my Form.
Here is my q-file input from my form, with the data.
<q-file
v-model="mealToSubmit.photo"
label="Upload File"
outlined
>
Data:
data () {
return {
mealToSubmit: {
name: '',
description: '',
photo: null,
grams: '',
calories: '',
visible: false
}
}
}
After I fill in the Form and click Save, all of the data appears on the page except for the photo I selected. In the console I get a 404 error:
404  http://localhost:8080/img/null 404 (Not Found)
I can see the problem here is that it's displaying null, instead of the name of the photo I upload, which is why I'm getting a 404 error.
Here are two screenshots, one of me filling in the Form and second is the data being displayed properly except for the photo, with the error message in the console.
NOTE:
Just to add to this, I've uploaded files before using Vue js and Bootstrap-Vue. I add an #change event on the File input with a v-model like this:
<b-form-group label="Upload Profile Photo (optional)" label-for="photo_id">
<b-form-file
v-model="profileData.photo_id"
id="photo_id"
placeholder="Choose a file..."
#change="attachImage"
accept=".jpg, .jpeg, .png"
></b-form-file>
</b-form-group>
Than in the Methods{}:
methods: {
attachImage(evt) {
const file = evt.target.files[0];
let reader = new FileReader();
reader.addEventListener('load', function() {
}.bind(this), false);
reader.readAsDataURL(file);
},
}
And then I bind the data using FormData(); and send it to the backend. This approach isn't working with the Quasar file upload input and the code that I have above.

I got it now:
<q-file
#input="getFile"
label="Upload file"
/>
methods: {
getFile(file) {
// file is in the file variable
this.mealToSubmit.photo = file
}
}

Related

Select the same file on Vuetify component v-file-input

I am building a web app using nuxt, vuetify 2.x, and typescript.
I want to upload file using v-file-input but have some issue upon selecting the same file.
For example, when I select some file and then close the dialog without saving it,
I cannot select the same file(i.e.#change is not firing)
what I have tried:
<v-file-input
accept="image/png, image/jpeg"
ref="imageUploader"
#click="resetImageUploader"
placeholder="upload image"
prepend-icon="mdi-camera"
#change="changeImage"
></v-file-input>
script:
methods: {
resetForm() {
(this.$refs.form as HTMLFormElement).reset();
},
resetImageUploader() {
(this.$refs.imageUploader as any).reset();
},
}
(resetForm() is called when dialog is closed)
I've tried resetting imageuploader when the input form is clicked, but it did not work.
I've tried (this.$refs.imageUploader as any).value = '' instead of reset() but it did not work.
Btw, When I select the file, clear icon appears like this
If I clear the form by clicking this icon, I can select the same file..
Does anyone have idea how I can solve this issue?
try to do like below to reset
<v-file-input
accept="image/png, image/jpeg"
ref="imageUploader"
:value="internalVal"
#click="resetImageUploader"
placeholder="upload image"
prepend-icon="mdi-camera"
#change="changeImage"
></v-file-input>
script:
methods: {
resetImageUploader() {
this.internalVal = []
},
}

How to render a template with VueJS and Axios?

I have a Vue app that generates as many forms as the user likes. Each form represent a 'risk' in this 'risks' data model:
var app = new Vue({
el: '#app',
data: {
risks: [
{
'risk_name': '', 'fields': [{'field': '', 'type': ''}], 'errors':[]
}
],
},
Then I send the 'risks' to a post API request. Then I make a second get request that brings back a template with the processed data as JSON. So far so good. However, how do I render the template (new page) with this data.
This is how I receive the data:
Submit() {
if (this.checkValidity()) {
console.info(this.risks)
axios.post('risks', this.risks)
.then(function(response) {
axios.get('risks')//This gets the data back
})
.catch(function(error) {
alert('This Error occured: ' + error)
})
}
},
This is the GET API call that I called above (Flask):
#app.route('/risks', methods=['GET'])
def getInsurancePolicyForm():
risks = getTables(app.metadata)
return render_template('form.html', risks=risks)
I can see the rendered template in developer tools, but the page the user sees remains the same.
Your page should be focussed on the risks object instead of the response from the API call.
When the user selects options, add them to the risks data object so your risks object looks like:
risks: [
{
'risk_name': '', 'fields': [{'field': 'My Field', 'type': 'text', modelToHoldData: ''}], 'errors':[]
}
]
Then, when the user clicks on Submit, by all means send it to the API but you don't need a template from there, use the risks object like so (remembering to hide the form they've just chosen their fields with):
<div v-for="risk in risks">
<label>{{risk.field}}</label>
<input type="text" v-if="risk.type === 'text'" v-model="risk.modelToHoldData" />
</div>
You can adjust the above example to add as many variations of the example as you allow the user to select.
Once all this is done and you need access to the data the user enters, you can loop through the array again and just access the modelToHoldData prop on each of the risks.

Vue.js form file input Error in event handler

I am trying to upload a file in my form using the bootstrap-vue form file component
template
<b-form-group id="userInputGroup8" label="User Picture:">
<b-form-file id="userPictureInput" ref="fileinput" #input="userPictureSelected" v-model="userPictureFile" choose-label="Select" accept=".jpg, .png"></b-form-file>
<br> Selected file : {{ userPictureFile.name }}
</b-form-group>
Once the file is selected , the name is displayed in the browser, but it does not appear in the input field, and even if the userPictureSelected method is fired, I don't get its value in the console
script
data () {
return {
...
userPictureFile: '',
}
},
methods: _.extend({}, mapActions(['createUser']), {
userPictureSelected: () => {
console.log('Selected: ', this.userPictureFile.name)
}
}
I get the error
[Vue warn]: Error in event handler for "input": "TypeError: _this2.userPictureFile is undefined"
What could be wrong ? where can I get a good and recent example for uploading such file into my server backend static files directory ?
thanks for update
seems to be an issue not yet solved with bootstrap-vue
Custom input file after choice file nothing change.

Vue.js - Element UI - Use upload component without POST request triggering

I'm using the upload component of Element UI. It unfortunately triggers a POST request as soon as a file is uploaded. What I'm aiming for is to push the files to an empty array which would be posted after with button.
HTML
// Element UI documentation says http-request overrides xhr behavior
// so I can use my own file request. In this case, I wanted to use a method
// though I'm not quite sure about this part?
<el-upload
action="",
:http-request="addAttachment",
:on-remove="deleteAttachment",
:file-list="attachments">
<el-button size="mini" type="primary">Add file</el-button>
</el-upload>
// button that uploads the files here
JS
data() {
attachments: []
},
methods: {
addAttachment ( file, fileList ) {
this.attachments.push( file );
},
deleteAttachment () {
// removes from array
}
}
Apparently, you also need to set the auto-upload prop to be false. Otherwise, it defaults to true and will automatically try to upload the file even if you've specified a function for the http-request prop.
In your case:
<el-upload
action="",
:http-request="addAttachment",
:auto-upload="false"
:on-remove="deleteAttachment",
:file-list="attachments"
>
<el-button size="mini" type="primary">Add file</el-button>
</el-upload>
Here's the documentation for the component.

Is it possible to add a custom Cloud file service (like OneDrive/Dropbox) to Outlook.com (Office 365)

I've seen that when you add an Attachment in Outlook, you can automaticly add an attachment from a cloud service.
Is there a possible way to add a custom entry to this list?
I offer to you to use OneDrive file picker , with this you can simply add button to your add-in html and then it's open the log-in page and after user is log-in he could choose the files from one drive.
The steps wrote in the link but I write the main steps here:
1.register your app in Microsoft Application Registration Portal .
2.Add the js refrence in your js file of your add-in:
<script type="text/javascript" src="https://js.live.net/v7.0/OneDrive.js">
</script>
3.Add button to your add-in html page:
<button class="oneDriveButton" id="btnOneDrive" ><img src="https://js.live.net/v5.0/images/SkyDrivePicker/SkyDriveIcon_white.png" style="margin-right: 10px; height: 20px;">Open from OneDrive</button>
4.In your js file of add-in open the picker:
$('#btnOneDrive').click(function () {
var odOptions = {
clientId: "your client id from your app registration ",
action: "download",
multiSelect: true,
openInNewWindow: true,
linkType: "query",
advanced: { redirectUri: "your redirect uri from app registration" },
success: function (files) {
},
cancel: function () { /* cancel handler */
},
error: function (e) { /* error handler */
}
};
OneDrive.open(odOptions); });
Put attention:
Your clientId and your redirectUri must be equal to this you
set when you register your app in the first step.
You could change the option by what you want ,look here under
picker options .
Thats all , you get the files in sucess handler function and you could do whatever you want with them.
Good luck!