How to upload multiple image in Vue.JS and axios (Vuex) - vue.js

all day I’m trying to solve the problem with multi-upload images
In console log im see all the data but when I try to write this data to a variable im get empty array
If someone have info about solve this problem I'll be very grateful
This is my code in Vue component for upload images
<div class="card-body">
<form>
<vue-upload-multiple-image
#upload-success="uploadImageSuccess(id)"
#before-remove="beforeRemove"
#edit-image="editImage"
:data-images="images"
idUpload="myIdUpload"
editUpload="myIdEdit"
></vue-upload-multiple-image>
</form>
</div>
This is my data in Vue Component
data()
{
return{
images: [],
}
},
This is my function from upload images in Vue Component
uploadImageSuccess(id, formData, index, fileList) {
this.images = fileList;
console.log(formData)
console.log(index)
console.log(fileList)
this.addNewGallery({id, data: this.images});
},
This is my code from Vuex Store from upload images
async addNewGallery(ctx, {id, data})
{
return new Promise((resolve, reject) => {
axios({
url: '/gallery/' + id,
method: 'PUT',
data: data,
})
.then((resp) => {
console.log(resp)
})
.catch((error) => {
console.log(error)
reject(error)
})
})
}
This is my code from Console tab in browser
[{…}, ob: Observer]
0:
name: "IPhoneX.png"
path: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAC7gA"
highlight: 1
default: 1

Related

Vue.js ReferenceError in event payload

I have a user profile page with an image. I'm uploading the image to Firebase Storage, updating the user's record in Firestore to point at the image and displaying it. I have everything working in a single component.
Now I want to refactor to put the image uploading functionality into its own component with the idea that the new component will return the url of the uploaded file so that the parent component can then update Firestore. The benefit being that I can re-use the image upload component on other pages without the uploader needing to know why it's uploading images. The way I have architected this is as follows:
<template>
...
<v-btn
:disabled="!file"
class="primary"
small
#click.prevent="selected">Upload</v-btn>
...
</template>
export default {
name: "BaseImageUploader",
props: {
accept: {
type: String,
default: () => "image/png, image/jpeg, image/bmp"
},
placeholder: {
type: String,
default: () => "Click to select an image to upload"
},
label: {
type: String,
default: () => "Profile Picture"
}
},
data: () => ({
file: null
}),
methods: {
selected() {
const fileRef = storage.child("corporate-wellness-1/" + this.file.name);
fileRef
.put(this.file)
.then(uploadTaskSnapshot => uploadTaskSnapshot.ref.getDownloadURL())
.then(url => this.$root.$emit("base-image-uploader", url))
}
}
};
then the parent listens for the event and updates Firestore like so:
...
mounted() {
this.$root.$on(`base-image-uploader`, (event) => {
this.uploadImage(event)
});
},
...
uploadImage(url) {
this.$store
.dispatch("user/updateProfileImageUrl", url)
.then(() => console.log('image url updated in bio'))
}
The problem is I'm getting
ReferenceError: url is not defined
on the dispatch in the parent component.
The event only gets emitted after the url becomes available in the child component, so I don't understand why it's not available in the parent when the event handler is called.
So, I've two questions:
Why doesn't the code written work?
And more generally, is there a better way to architect it?

How to delete data using Vue.axios.delete()

I am new to vuejs. I am having trouble deleting json data from a fakeserve by using axios.delete().
I tried doing this :-
axios.delete('http://localhost:3000/users/', {params: {id: this.idToDelete} })
.then((response) => {
console.log(response)
}, (error) => {
console.log(error)
})
This is my html:-
<v-text-field v-model="idToDelete" type="number" hide-details outline
label="Enter Id to delete"></v-text-field>
<v-btn #click="userIdtoDelete()" color="error">Delete</v-btn>
This is my javascript (src/views/pages/Delete.vue):
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
export default {
data () {
return {
idToDelete: ''
}
},
methods: {
userIdtoDelete () {
axios.delete('http://localhost:3000/users/', {params: {id: this.idToDelete} })
.then((response) => {
console.log(response)
//alert('response = ' + response)
}, (error) => {
console.log(error)
//alert('error = ' + error)
})
}
}
}
My code is in https://github.com/boidurja/users.git
And fakeserver is in https://github.com/boidurja/fakeserver.git
When I click the delete button data is not getting deleted and I am getting the following error message:-
DELETE http://localhost:3000/users/?id=3 404 (Not Found)
JSON Server automatically creates routes in a RESTful format, eg
GET /users
GET /users/1
POST /users
PUT /users/1
PATCH /users/1
DELETE /users/1
So with that in mind, you should be using
axios.delete(`http://localhost:3000/users/${encodeURIComponent(this.idToDelete)}`)
.then(res => { console.log(res) })
.catch(err => { console.error(err) })
I think your issue is that you are calling a function inline with () vue does this for you, try
<v-btn #click="userIdtoDelete" color="error">Delete</v-btn>
I think you are triggering the function twice.
In addition, you can try instead of using v-model to catch the id directly in the function like userIdtoDelete($event.target.value)

How To Attach File On Axios Post Request In Vue

Hello I am trying to attach file for axios.post however when I do a console.log() the formData is empty so here is what I am working with.
On my vue form
<form #submit.prevent="uploadTodos">
<div>
<input type="file" v-on:change="selectedFile($event)">
<label>Choose file</label>
</div>
<button type="submit">Submit</button>
</form>
Here is the data object
data() {
return {
file: null,
}
}
and method I have for the selectedFile on change event
selectedFile(event) {
this.file = event.target.files[0]
},
and here is the submit event method
uploadTodos() {
let formData = new FormData
formData.append('file', this.file)
this.$store.dispatch('uploadTodos', formData)
}
and here is the store method being dispatch
uploadTodos(context, file) {
console.log(file)
axios.post('/import', file,{ headers: {
'Content-Type': 'multipart/form-data'
}})
.then(response => {
console.log(response.data)
context.commit('importTodos', response.data)
})
.catch(error => {
console.log(error.response.data)
})
}
and when I console.log(file) I get the formData I created in the uploadTodos() method however it is empty, So I am trying to figure out why it is empty?
any help would be greatly appreciated

VueJS does not update DOM after fetch data from API?

I am trying to create an example about the list of photos and I see a trouble when binding data to the component after call API.
JS code:
<script>
// photo item
Vue.component('photo-item', {
props: ['photo'],
template: `<li>{{ photo.name }}</li>`
});
// List of photos
Vue.component('photo-list', {
props: ['photos'],
template: `
<ul id="photo-list">
<photo-item v-for="photo in photos" :photo="photo"></photo-item>
</ul>`
});
new Vue({
el: "#photo_detail",
data: {
photos: []
},
created: function() {
axios
.get('/api/photos')
.then(function (response) {
this.photos = response.data; // Data existed
})
.catch(function (err) {
console.log(err);
});
}
})
</script>
HTML code
<main id="photo_detail">
<photo-list v-for="photo in photos" :photo="photo"></photo-list>
</main>
After fetching all photos from API and as my understand then the variable photos will auto binding and VueJS will update DOM.
VueJs 2.1.6
Any help.
Thanks!
Issue is with your this value inside function() which has this value scoped to axios instead of vue instance .
or you can use (response)=> to use this directly
new Vue({
el: "#photo_detail",
data: {
photos: []
},
created: function() {
var self=this;
axios
.get('/api/photos')
.then(function (response) {
self.photos = response.data; // Data existed
})
.catch(function (err) {
console.log(err);
});
}
})
Your code is not correct.
Problems:
It will be better to define used components for each component, like
components: {photoItem}.
In your axios callback you use function and that means, that you use wrong context inside (this.photos). Use arrow function
(() => {}) instead of the function () {}
The directive v-for requires directive :key=""
I've fixed it below.
// photo item
const photoItem = Vue.component('photo-item', {
props: ['photo'],
template: `<li>{{ photo.name }}</li>`
});
// List of photos
const photoList = Vue.component('photo-list', {
// define used components
components: {photoItem},
props: ['photos'],
template: `
<ul id="photo-list">
<!-- add :key="" directive -->
<photo-item v-for="(photo, index) in photos" :key="index" :photo="photo"></photo-item>
</ul>`
});
new Vue({
el: "#photo_detail",
// define used components
components: {photoList},
data: {
photos: []
},
created: function() {
// axios.get('/api/photos')
// use arrow function
setTimeout(() => {
this.photos = [{name: 'Photo 1'}, {name: 'Photo 2'}];
}, 1000);
}
})
<script src="https://unpkg.com/vue"></script>
<main id="photo_detail">
<photo-list :photos="photos"></photo-list>
</main>

VueJS data from nested Axios requests not rendering in view

I am trying to list a set of posts from an API on a page using VueJS and Axios. The issue I am facing is one piece of the data (the post url) needs to be retrieved with a separate API call for that specific post and they provide the url for that data in the initial API call. I have the first part working perfectly, but I can't get the href to render in the view when the value is showing up in the Vue devtools.
JS
const vm = new Vue({
el: '#app',
data: {
posts: []
},
mounted() {
this.getPosts();
},
methods: {
getPosts() {
axios.get("api_url")
.then((response) => {
this.posts = response.data.posts;
// Get URL for each post from separate API call
this.posts.map(post => {
axios.get(post.details_url+"&output=json")
.then((response) => {
post.official_url = response.data.post.pet_details_url;
}).catch( error => { console.log(error); });
});
}).catch( error => { console.log(error); });
}
}
});
HTML
<div id="app">
<div v-for="post in posts">
<a :href="post.official_url"> //href won't render
<h2>{{ post.title }}</h2>
<p>{{ post.text }}</p>
</a>
</div>
</div>
Data showing up in Vue DevTools
It might be reactive problem. You can try Vue.set
getPosts() {
let vm = this
axios.get("api_url")
.then((response) => {
this.posts = response.data.posts;
// Get URL for each post from separate API call
this.posts.map((post, index) => {
axios.get(post.details_url+"&output=json")
.then((response) => {
post.official_url = response.data.post.pet_details_url;
Vue.set(vm.posts, index, JSON.parse(JSON.stringify(post)))
}).catch( error => { console.log(error); });
});
}).catch( error => { console.log(error); });
}