Vuejs and vue-qrcode-reader add beep scan - vue.js

Hello I use the library view-qrcode-reader for QR Code scan. I try to add a BEEP scan but I do not feel that the library does this kind of thing. So I did the thing manually but it does not work either.
<template>
<div class="container" id="app">
<router-link class="waves-effect waves-light btn" to="/livreur"><i class="material-icons">arrow_back</i>
</router-link>
<div class="row center">
<span v-if="errors" class="card-panel white-text red darken-1"><strong>{{ errors }}</strong></span>
</div>
<div class="row infos">
<span v-if="infos" class="card-panel white-text green green-1"><strong>Email & SMS envoyé à {{ infos.firstname }} {{ infos.lastname }}</strong></span>
</div>
<br/>
<div class="row">
<qrcode-stream #decode="onDecode"></qrcode-stream>
</div>
</div>
</template>
<script>
var attributes = {
setting: {
soundSrc: '/sounds/beep.mp3'
}
}
export default {
name: 'prepa',
data () {
return {
infos: '',
errors: '',
success: ''
}
},
methods: {
onDecode (decodedString) {
var audio = new Audio(attributes.setting.soundSrc)
audio.play()
this.$http.get('/orders/delivery/prepa/' + decodedString, {headers: {Authorization: `Bearer ${localStorage.token}`}})
.then(request => this.trackingInfos(request))
.catch((request) => this.trackingFail(request))
},
trackingInfos (req) {
if (req.data.error) {
return this.trackingFail(req)
}
this.errors = ''
this.infos = req.data.datas
this.save()
},
trackingFail (req) {
if (req.data.error) {
this.errors = req.data.error
}
},
save () {
this.$http.post('/order_histories', {
location: this.infos.city,
status: '/api/order_statuses/' + this.$preparation,
User: '/api/users/' + localStorage.userId,
orderId: '/api/orders/' + this.infos.orderId,
headers: {Authorization: `Bearer ${localStorage.token}`}
})
.then(request => this.successPrepa(request))
.catch(() => this.failPrepa())
},
successPrepa (req) {
if (req.data.error) {
return this.failPrepa(req)
}
this.errors = ''
this.success = req.status
},
failPrepa (req) {
if (req.data.error) {
this.errors = req.data.error
}
}
}
}
</script>
No beep and an error that appears in the console.
:8080/sounds/beep.mp3:1 GET http://127.0.0.1:8080/sounds/beep.mp3 net::ERR_ABORTED 404 (Not Found)
:8080/#/prepa:1 Uncaught (in promise) DOMException
Thanks for your help.

Related

Losing my data when i refresh page in vuejs

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))
}
}
}

input field value keeps getting reset #input?

I have created an custom reusable autocomplete component.The issue i am facing is whenever i start to type anything into the fields(#input) the value in the input field gets reset. I feel it has something to do within the code written in the debounce function but i am not sure.Plz help?
main.js
Vue.component('AutoComplete', {
props: ['list','value','title'],
data() {
return {
input: '',
}
},
template: `<template>
<div class="autocomplete">
<input style="font-size: 12pt; height: 36px; width:1800px; " type="text" v-model="input" #input="handleInput"/>
<ul v-if="input" >
<li v-for="(item, i) in list" :key="i" #click="setInput(item)" >
<template v-if="title!='manager'">
<div class="container">
<p>
<b>ID:</b>
{{item.id}}
</p>
<p>
<b>Description:</b>
{{item.description}}
</p>
</div>
</template>
<template v-else>
<div class="container">
<p>
<b>ID:</b>
{{item.id}}
</p>
<p>
<b>First Name:</b>
{{item.firstName}}
</p>
<p>
<b>Last Name:</b>
{{item.lastName}}
</p>
</div>
</template>
</li>
</ul>
</div>
</template>`,
methods: {
handleInput(e) {
console.log('inside handleInput')
this.$emit('input', e.target.value)
},
setInput(value) {
console.log('inside setInput')
this.input = value
this.$emit('click', value)
}
},
watch: {
$props: {
immediate: true,
deep: true,
handler(newValue, oldValue) {
console.log('new value is'+newValue)
console.log('old value is'+oldValue)
console.log('value inside handler'+this.value)
console.log('list inside handler'+this.list)
console.log('title inside handler'+this.title)
this.input=this.value
}
}
}
})
Currently i have called this component from JobDetail.vue page like this-
JobDetail.vue
<template>
<b-field label="Custom Action">
<AutoComplete v-on:input="getAsyncDataAction" v-on:click="(option) => {updateRowValue('records', props.index, 'action', option.id); props.row.action = option.id}" :value="props.row.action" :list="dataAction" title='action' >
</AutoComplete>
</b-field>
</template>
<script>
import { viewMixin } from "../viewMixin.js";
import debounce from "lodash/debounce";
import api from "../store/api";
const ViewName = "JobDetail";
export default {
name: "JobDetail",
mixins: [viewMixin(ViewName)],
data() {
return {
dataAction: [],
isFetching: false
};
},
methods: {
getAsyncDataAction: debounce(function(name) {
if (!name.length) {
this.dataAction = [];
return;
}
this.isFetching = true;
api
.getSearchData(`/action/?query=${name}`)
.then(response => {
this.dataAction = [];
response.forEach(item => {
this.dataAction.push(item);
});
})
.catch(error => {
this.dataAction = [];
throw error;
})
.finally(() => {
this.isFetching = false;
});
}, 500)
}
};
</script>
viewmixin.js
computed: {
viewData() {
return this.$store.getters.getViewData(viewName)
},
objectData() {
return this.$store.getters.getApiData(this.viewData.api_id).data
},
sessionData() {
return this.$store.getters.getSessionData()
},
isLoading() {
return this.$store.getters.getApiData(this.viewData.api_id).isLoading
},
newRecord() {
return this.$route.params.id === null;
}
},
I don't understand why the input fields value keeps resetting #input. Please help and also let me know if this is the correct approach?

Vue el-form dynamic validation

<template>
<div>
<el-form label-position="top" :model="notificationEmails" ref="emailForm">
<el-form-item
v-for="(item, index) in notificationEmails.emails"
:key="index"
:label="getLabel(index)"
:for="`${item.id}_${index}`"
:prop="'emails.' + index + '.id'"
:rules="{
required: true,
type: 'email',
message: 'Not valid email',
trigger: ['blur', 'change']
}"
>
<el-row>
<el-col :span="6">
<el-input v-model="item.id" type="email" :id="`${item.id}_${index}`" />
</el-col>
<el-col :span="2" style="padding-left: 18px">
<span v-if="index === 0" tabindex="0" #click="addEmail" #keyup.enter.stop="addEmail">
<i aria-hidden="true" class="icon-add-circle-outline" />
<span class="screen-reader">{{$t('a11y.settings.soldTo.notif.action.addEmail')}}</span>
</span>
<span
v-else
tabindex="0"
#click="deleteEmail(item.id)"
#keyup.enter.stop="deleteEmail(item.id)"
>
<i class="icon-subtract-circle-outline" aria-hidden="true" />
<span class="screen-reader">{{$t('a11y.settings.soldTo.notif.action.deleteEmail')}}</span>
</span>
</el-col>
</el-row>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
name: 'EmailWidget',
data() {
return {
notificationEmails: {
emails: []
}
};
},
props: ['passEmail'],
watch: {
passEmail: {
handler(newVal) {
this.notificationEmails.emails = newVal;
},
deep: true
},
notificationEmails: {
handler() {
this.$refs.emailForm.validate(async validate => {
if (validate) {
await this.$store.dispatch('settings/GENERIC', {
module: 'common',
propKey: 'validEmail',
propValue: true
});
} else {
await this.$store.dispatch('settings/GENERIC', {
module: 'common',
propKey: 'validEmail',
propValue: false
});
}
});
},
deep: true
}
},
methods: {
addEmail() {
this.notificationEmails.emails.push({
id: '',
priority: this.notificationEmails.emails.length + 1
});
// this.emails = [...this.emails, { id: '', priority: this.emails.length + 1 }];
},
deleteEmail(email) {
// this.emails = this.emails.filter(item => item.id !== email);
let index = 0;
for (let i = 0; i < this.notificationEmails.emails.length; i += 1) {
if (this.notificationEmails.emails[i].id === email) {
index = i;
break;
}
}
this.notificationEmails.emails.splice(index, 1);
},
getLabel(index) {
return index === 0 ? this.$t('settings.soldTo.notif.email') : '';
}
},
};
</script>
<style lang="scss">
i:hover {
cursor: pointer;
}
</style>
Some problems about the validation in dynamic add or delete the emails in el-form of Vue. When I add a new email, the validation cannot work. When I delete email. it shows
Error: please transfer a valid prop path to form item!
There is no issue when I edit the email.
I change the props according to enter code here the official document, but it still shows error.

How to correctly bind a component property that is updated by a webservice in vuejs

I have a simple page that gets its data from a set of web services and they are called in an interval. I want to update the page every time the web services gets new data.
My current issue is that while I am getting the data but the child component are not updating themselves and are not showing themselves at all. I have also tried this with static data which works correctly so I am guessing that I am not binding the properties correctly.
Below is the html and script pages
<div class="columns" id="app">
<div class="column">
<process-list v-bind:processesInfo="serverProcesses"></process-list>
</div>
<div class="column">
<article class="message is-info">
<div class="message-header">
<p>System info</p>
</div>
<div class="message-body">
<pre> <code> {{ memoryResponse }} </code></pre>
<pre>memory and Storage info </pre>
</div>
</article>
</div>
</div>
script
Vue.config.devtools = true
Vue.component('process-info', {
template:' <article class="message is-info">' +
' <div class="message-header">' +
' <p> {{ process.Process }} id: {{ process.ProcessID }}</p>' +
' </div>' +
' <div class="message-body">' +
' <ul>' +
' <li><strong>I/O Writes (Bytes per sec) : </strong> {{ process.IOWrites }} </li>' +
' <li><strong>Virtual Bytes : </strong> {{ process.VirtualBytes }} </li>'+
' <li><strong>Virtual Bytes Peak : </strong> {{ process.VirtualBytesPeak }}</li>'+
' <li><strong>Working Set : </strong> {{ process.WorkingSet }}</li>'+
' <li><strong>Working Set Peak : </strong> {{ process.WorkingSetPeak }}</li> '+
' <li><strong>% Processor Time : </strong> {{ process.ProcessorTime }}</li>' +
' </ul>' +
' </div>' +
' </article>',
props:['process']
});
Vue.component('process-list', {
template:' <div><div v-for="process in processesInfo"> ' +
' <process-info v-bind:process="process"></process-info>'+
'</div></div>' ,
props:['processesInfo'],
// watch:{
// processesInfo(value) {
// this.myProps = value.Processes
// }
// },
// data() {
// return {
// /* processesInfo: [
// {"Process": "edmserver","ProcessID": "20792","IOWrites": "267","VirtualBytes": "4.294967E+09 MB","VirtualBytesPeak": "4.294967E+09 MB","WorkingSet": "1.387725E+07 MB","WorkingSetPeak": "3.692052E+08 MB","ProcessorTime": "0"},
// {"Process": "edmappserver","ProcessID": "17372","IOWrites": "96","VirtualBytes": "4.294967E+09 MB","VirtualBytesPeak": "4.294967E+09 MB","WorkingSet": "5.326848E+07 MB","WorkingSetPeak": "8.826388E+08 MB","ProcessorTime": "0"}
// ] */
// }
// },
})
var app = new Vue({
el: '#app',
data: {
serverProcesses : [],
serverInfo : null,
backupResponce : 'No data!',
memoryResponse : 'No data!',
edmStatusInterval: null,
edmStatusAttemptNumber : 0,
interval : 5000
},
methods: {
pullingEDMstatus : function() {
this.edmStatusInterval = setInterval(this.checkEDMstatus, this.interval);
},
stopPullings : function() {
clearInterval(this.edmStatusInterval);
},
checkEDMstatus : function() {
this.edmStatusAttemptNumber += 1;
fetch(getEDMstatusUrl(), {
method: "POST",
headers: {
"Content-Type": "text/plain"
}
})
.then(response => response.json())
.then(data => {
this.serverProcesses = JSON.stringify(data.Processes, null, 4)
this.serverInfo = JSON.stringify(data.System, null, 4)
})
.catch(error => {
if(error.message === 'Failed to fetch') {
generateErrorMsg('503','Service Unavailable')
} else {
generateErrorMsg('', error.message)
}
})
}
},
beforeDestroy() {
clearInterval(this,polling)
},
created() {
this.pullingEDMstatus()
}
})
I tried to use the v-bind but this does not work here and I don't know what I'm doing wrong. Also I have read that I need to use a watch when the parent property is updated but again did not work for me.
By the way this is my first attempt with vuejs so links and examples are appreciated.
cheers,
es
To solve this problem I moved the methods from the main to the components themselves
Vue.component('process-list', {
template:' <div><div v-for="process in processesInfo"> ' +
' <process-info v-bind:process="process"></process-info>'+
'</div></div>' ,
data() {
return {
processesInfo : [],
statusInterval: null,
interval : 5000
}
},
methods: {
pullingStatus : function() {
this.statusInterval = setInterval(this.checkStatus, this.interval);
},
checkStatus : function() {
this.statusAttemptNumber += 1;
fetch(getStatusUrl(), {
method: "POST",
headers: {
"Content-Type": "text/plain"
}
})
.then(response => response.json())
.then(data => {
this.processesInfo = data.Processes
})
.catch(error => {
if(error.message === 'Failed to fetch') {
generateErrorMsg('503','Service Unavailable')
} else {
generateErrorMsg('', error.message)
}
})
}
},
beforeDestroy() {
clearInterval(this,polling)
},
created() {
this.pullingStatus()
}
})
var app = new Vue({
el: '#app',
data: {
serverInfo : null,
backupResponce : 'No data!',
memoryResponse : 'No data!',
statusAttemptNumber : 0,
}
})
cheers,
es

Vue 2 Emit selected data back to parent component

Struggling to sort out how to get a selected value from a Typeahead component to pass back to the parent component. I'm allowing the user to search from a variety of data to link a record to a post. Once the user clicks one of the typeahead drop-down records, I pass the item to the sendlink method - I've checked that the data passes ok. When I do the emit using the selected-link event, I'm not getting the data in the parent component.
PostList.vue
<template>
<div>
<div v-if='posts.length === 0' class="header">There are no posts yet!</div>
<form action="#" #submit.prevent="createPost()" class="publisher bt-1 border-fade bg-white" autocomplete="off">
<div class="input-group">
<input v-model="post.content" type="text" name="content" class="form-control publisher-input" placeholder="What's the lastest?" autofocus>
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">Post</button>
</span>
</div>
<span class="publisher-btn file-group">
<i class="fa fa-camera file-browser"></i>
<input type="file">
</span>
</form>
<div #click="doit" v-on:selected-link="onSelectedLink">{{ modellink.name }}</div>
<typeahead
source="/api/typeahead"
placeholder="Link Post to Trip, Business, etc"
filter-key="title"
:start-at="3">
</typeahead>
<post v-for="post in posts"
:key="post.id"
:post="post"
#post-deleted="deletePost($event)">
</post>
</div>
</template>
<script>
var axios = require("axios");
import post from './PostItem.vue';
import typeahead from './Typeahead.vue';
export default {
components: {
post,
typeahead
},
props: ['postableId', 'postableType', 'model'],
data: function() {
return {
modellink: {
"name": "n/a",
"description": "",
"id": null,
"model": "n/a"
},
post: {
id: 1,
content: "",
edited: false,
created_at: new Date().toLocaleString(),
user: {
id: 1,
name: '',
}
},
posts: [
{
id: 1,
content: "",
edited: false,
created_at: new Date().toLocaleString(),
user: {
id: 1,
name: '',
}
}
]
};
},
created() {
this.fetchPostsList();
},
methods: {
onSelectedLink: function (talink) {
alert(JSON.stringify(talink, null, 4));
this.link = talink
},
doit() {
alert(JSON.stringify(this.modellink, null, 4));
},
fetchPostsList() {
if( this.postableId ) {
axios.get('/api/' + this.postableType + '/' + this.postableId + '/posts').then((res) => {
this.posts = res.data;
});
} else {
axios.get('/api/post').then((res) => {
//alert(JSON.stringify(res.data[0], null, 4));
this.posts = res.data;
});
}
},
createPost() {
axios.post('api/post', {content: this.post.content, user_id: Laravel.userId, vessel_id: Laravel.vesselId })
.then((res) => {
this.post.content = '';
// this.post.user_id = Laravel.userId;
// this.task.statuscolor = '#ff0000';
this.edit = false;
this.fetchPostsList();
})
.catch((err) => console.error(err));
},
deletePost(post) {
axios.delete('api/post/' + post.id)
.then((res) => {
this.fetchPostsList()
})
.catch((err) => console.error(err));
},
}
}
</script>
Typeahead.vue
<template>
<div>
<input
v-model="query"
#blur="reset"
type="text"
class="SearchInput"
:placeholder="placeholder">
<transition-group name="fade" tag="ul" class="Results">
<li v-for="item in items" :key="item.id">
<span #click="sendlink(item)">
<strong>{{ item.name }}</strong> - <small>{{ item.model }}</small><br>
<small>{{ item.description }}</small>
</span>
</li>
</transition-group>
<p v-show="isEmpty">Sorry, but we can't find any match for given term :( </p>
</div>
</template>
<script>
var axios = require("axios");
export default {
name: 'Typeahead',
props: {
modellink: {
type: Object,
required: false
},
source: {
type: [String, Array],
required: true
},
filterKey: {
type: String,
required: true
},
startAt: {
type: Number,
default: 3
},
placeholder: {
type: String,
default: ''
}
},
data() {
return {
items: [],
query: '',
taitem: ''
}
},
computed: {
lookup() {
if(this.query.length >= this.startAt) {
axios.get(this.source + '/' + this.query).then((res) => {
this.items = res.data;
return res.data;
});
}
},
isEmpty() {
if( typeof this.lookup === 'undefined' ) {
return false
} else {
return this.lookup.length < 1
}
}
},
methods: {
sendlink: function (taitem) {
this.$emit('selected-link', taitem);
},
reset() {
this.query = ''
}
}
}
</script>
In your PostList.vue, move the v-on:selected-link="onSelectedLink" from the div to typeahead like below. When emitting an event from child to parent, the listener on the parent needs to be on the child component tag for it to work.
<div #click="doit">{{ modellink.name }}</div>
<typeahead
source="/api/typeahead"
placeholder="Link Post to Trip, Business, etc"
filter-key="title"
:start-at="3"
v-on:selected-link="onSelectedLink">
</typeahead>