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!
Related
I am trying to make some API calls via MsGraph from Chrome-extension.I am using Vue2 to build this extension and 'vue-msal'. When I print msal object it gets in this format:
But when I call it I get nothing.It suppose to open a logIn window.
<div id="demo">
<div v-if="user">
<div>Welcome {{user.name}}</div>
<div v-if="user.profile.jobTitle">Your job title is {{user.profile.jobTitle}}</div>
<div><button #click="signOut()">logout</button></div>
</div>
<div v-else>
<button #click="signIn()"> Please sign-in</button>
</div>
</div>
</template>
<script>
import { msalMixin } from 'vue-msal';
export default {
mixins: [msalMixin],
name: 'HelloWorld',
mounted () {
},
computed: {
user() {
let user = null;
if (this.msal.isAuthenticated) { // Note that the dollar sign ($) is missing from this.msal
user = {
...this.msal.user,
profile: {}
}
if (this.msal.graph && this.msal.graph.profile) {
user.profile = this.msal.graph.profile
}
}
return user;
}
},
methods:{
async signIn(){
console.log(this.$msal,'msal')
console.log(this.$msal.signIn(),'signIn func')
},
signOut(){
this.$msal.signOut()
}
}
}
</script>
I'm creating a social network for project in my formation, i have a like system and it work.
i have a components cardArticle with all info and i try to do a like count. It work but when i refresh the page or going on other page, i lost all my data likes (my data is not saved)
components/CardArticle.vue
<template>
<div id="card">
<div>
<a class="cardLink">
<img class="card-img" v-if="post.imageUrl !== undefined" :src="post.imageUrl" />
<h2 class="cardTitle"> {{ post.title }}</h2>
<p class="cardDescription"> {{ post.description }}</p>
</a>
</div>
<div class="buttonIcon">
<div>
<button type="button" class="buttonDelete" id="buttonDelete" #click="deletePost"
v-if="this.post.userId === this.user.userId || this.user.isAdmin === true">Supprimer</button>
<button type="button" class="buttonEdit" id="buttonEdit" #click="modifyPost"
v-if="this.post.userId === this.user.userId || this.user.isAdmin === true">
Editer
</button>
</div>
<div class="divIconLike">
<div class="iconLike">
<a #click="sendLike">
<i class="fa-regular fa-thumbs-up"></i>
</a>
</div>
<div class="countLike">
<p> {{ likes }} </p>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import router from "../router/index.js";
export default {
name: 'CardArticle',
data () {
return {
likes: 0
}
},
props: {
post: {
type: Object
}
},
computed: {
user() {
return this.$store.getters.user;
}
},
methods: {
sendLike() {
axios.post("http://localhost:3000/api/articles/" + this.post._id + "/like", {
userId: this.user.userId
}, {
headers: {
Authorization: "Bearer " + this.user.token
}
})
.then(response => this.likes = response.data.article.likes)
.catch(error => console.log(error))
}
}
}
</script>
views/home.vue
<template>
<div class="home" v-if="this.user.token !== null">
<CardArticle v-for="post in allPosts" v-bind:key="post.id" :post="post" />
</div>
</template>
<script>
import CardArticle from "../components/CardArticle.vue"
import axios from "axios";
export default {
name: 'HomeArticle',
data () {
return {
post: {
title: "",
description: "",
imageUrl: ""
},
allPosts: [],
}
},
computed: {
user() {
return this.$store.getters.user;
}
},
components: {
CardArticle,
},
mounted() {
axios.get("http://localhost:3000/api/articles", {
headers: {
Authorization: "Bearer " + this.user.token
}
})
.then(response => {
this.allPosts = response.data;
})
.catch(error => {
return error;
})
}
}
</script>
What i should do for not losing my data ?
I would not use vuex or localstorage for that if possible, you have idea ?
Thanks for your help
If you loading data from server, then refresh page, you always will be lose data, because browser loading page again from server, and application will load data again.
If you don't want use vuex (but why not?), you can write data to cookies (by setting cookie value), then load it on app startup (when page is loaded). But it's not best practice at all. You can use vue3-cookies lib (link).
By the way, better learn to use stores, most progressive, I think, is Pinia.
Check: https://pinia.vuejs.org/
i lost all my data likes (my data is not saved)
likes is belong to each articles and It should have been saved to your db and call API to retrieve it again on component mounting:
export default {
name: 'CardArticle',
data () {
return {
likes: 0 // It's not managed by component state
}
},
methods: {
sendLike() {
axios.post("http://localhost:3000/api/articles/" + this.post._id + "/like", {
userId: this.user.userId
}, {
headers: {
Authorization: "Bearer " + this.user.token
}
})
.then(
// invalidates, update allPosts props (emit to parent)
)
.catch(error => console.log(error))
}
}
}
I'm create a an component which represents my money field.
My target is on add element in list, set zero on money field to add next element in list...
But, my problem is that not working when send using $emit event to clear input to improve usability.
$emit works as described on image bellow
My money field:
<template>
<div class="input-group" #clear="clearInputField()">
<span>{{ title }}</span>
<input ref="displayMoney" type="text" v-model="displayMoney" #focus="isActive = true" #blur="isActive = false" />
</div>
</template>
<script>
export default {
props: {
title: String,
},
data() {
return {
money: 0,
isActive: false,
};
},
methods: {
clearInputField() {
console.log("Its work event");
this.money = 0;
this.displayMoney = "";
},
},
computed: {
displayMoney: {
get: function () {
if (this.isActive) {
return this.money;
} else {
return this.money.toLocaleString("pt-br", { style: "currency", currency: "BRL" });
}
},
set: function (modifiedMoney) {
let newMoney = parseFloat(modifiedMoney.replace(/[^\d.]/g, "."));
if (isNaN(newMoney) || newMoney.length == 0) {
newMoney = 0;
}
this.$emit("input", newMoney);
return (this.money = parseFloat(newMoney));
},
},
},
};
</script>
My principal component
<template>
<div class="wish-list">
<div class="row">
<div class="input-group">
<span>Digite sua meta: </span>
<input ref="descriptionWish" type="text" v-model="descriptionWish" />
</div>
<MoneyField title="Valor (R$): " v-model="valueWish" #keyup.native.enter="addWish" />
<button id="btnCalculate" #click="addWish()">Adicionar a lista de desejos</button>
</div>
<div class="list-items">
<ul>
<li v-for="wish in wishes" :key="wish">{{ wish }}</li>
</ul>
</div>
</div>
</template>
<script>
import MoneyField from "./Fields/MoneyField";
export default {
components: {
MoneyField,
},
data() {
return {
wishes: [],
valueWish: 0,
descriptionWish: "",
};
},
methods: {
addWish() {
if (!isNaN(this.valueWish) && this.valueWish > 0 && this.descriptionWish.length > 0) {
this.wishes.push(
`${this.descriptionWish} => ${this.valueWish.toLocaleString("pt-BR", { currency: "BRl", style: "currency" })}`
);
this.descriptionWish = "";
console.log("addWish");
this.valueWish = 0;
this.$emit("clear");
this.$refs.descriptionWish.focus();
}
this.valueWish = 0;
},
},
};
</script>
I still don't understand much about vueJS, but I believe it's something related to parent and child elements, but I've done numerous and I can't get my answer.
sorry for my bad english .
The emit sends an event from the child to the parent component not as you've done, to run a method from the child component you could add a ref in the component inside the parent one like :
<MoneyField title="Valor (R$): "
ref="moneyField" v-model="valueWish" #keyup.native.enter="addWish" />
then run this.$refs.moneyField.clearInputField() instead this.$emit("clear")
I'am working with vuejs and firestore.I'am trynig to make my data change without refreshing page. the code below add me new line when i change the value on firestore.
value before changing:
value after changing:
my code:
{
<template>
<div id="dashboard">
<ul class="collection with-header">
<li class="collection-header"><h4>PLC</h4></li>
<li v-for="post in plc_value" v-bind:key="" class="collection-item">
<div class="chip">{{post.value_g}}</div>
<router-link class="secondary-content" v-bind:to="{ name: '', params:{} }"><i class="fa fa-eye"></i></router-link>
</li>
</ul>
</div>
</div>
</template>
<script>
import db from './firebaseInit';
export default {
name: 'dashboard',
data() {
return {
plc_value: [],
// loading: true
};
},
created() {
db
.collection('plc_value')
.onSnapshot(snap => {
snap.forEach(doc => {
const data = {
id: doc.id,
value_g: doc.data().value_g
};
this.plc_value.push(data);
});
});
}
};
</script>
}
In your created function, do this:
created() {
db
.collection('plc_value')
.onSnapshot(snapshot => {
const documents = snapshot.docs.map(doc => {
const data = {
id: doc.id,
value_g: doc.data()
}
return data
});
this.plc_value.push(documents);
});
});
}
I have a vue component which immediately after download sends axios request.
Also i use vue-social-sharing and i need og:image meta, but my image returns after axios respond.
<template>
<div class="container">
<div v-if="collageSrc" class="col-md-12 collage">
<img class="img-responsive" :src="this.collageSrc"/>
<social-sharing>
<div>
<network network="facebook">
<i name="fa fa-facebook"></i> Facebook
</network>
<network network="twitter">
<i class="fa fa-twitter"></i> Twitter
</network>
</div>
</social-sharing>
</div>
<div class="col-md-12 collage" v-else>
<h1>Your image is preparing...</h1>
</div>
</div>
</template>
<script>
export default {
name: 'collage',
props:['id'],
data: function(){
return {
collageWaiter: this.getCollageSrc(),
collageSrc: '',
url : '',
}
},
metaInfo: {
title : 'Compliment Genarator Collage',
meta: [
{charset : 'utf-8'},
{
'vmid' : 'og:image',
'property' : 'og:image',
//'content' : this.collageSrc
}
]
},
methods:{
getCollageSrc(){
const self = this;
axios.get('/api/generate?id='+this.id)
.then(function(result){
self.collageSrc = result.data;
self.url = "http://compgen.ru/collage/" + self.id;
});
}
}
}
</script>
as you can see, prop 'collageSrc' becomes available after axios request. How can i dynamic include this prop to meta og:image ?
Define metaInfo as function, not as object:
metaInfo() {
return {
meta: [
{ vmid: 'og:image', property: 'og:image', content: this.collageSrc }
]
}
}
https://vue-meta.nuxtjs.org/faq/component-props.html