VueJS: setInterval method not working properly - vue.js

Please tell me what am i doing wrong? I want to active 'cloth' update every 2 sec. Still learning vue. Thanks
data() {
return {
clothes: ['t-shirts', 'sneakers', 'jackets'],
count: 0,
cloth: ''
}
},
methods: {
startInterval() {
setInterval(() => {
this.cloth = this.clothes[this.count]
this.count++
if (this.count >= this.clothes.length) {
this.count = 0;
}
}, 2000)
}
}

Vue has a life cycle that you can leverage to complete this objective. You can hook into the created function and execute your interval within:
created() {
this.startInterval()
},
This is not a method. It will be a sibling to your data and method properties.

Related

realtime clock with vue js

I've written a small clock component for one of my projects,
but I didn't get the value for my clock refreshed.
A short extract of my code:
time() {
let now = new Date();
let hour = this.zeroPadding(now.getHours());
let minute = this.zeroPadding(now.getMinutes());
let second = this.zeroPadding(now.getSeconds());
console.log(hour.toString() + minute.toString() + second.toString())
if(!this.realtime)
return this.value
else
return hour.toString() + ":" + minute.toString() + ":" + second.toString()
}
},
mounted() {
setInterval(() => {
this.time()
}, 1000)
},
beforeDestroy () {
clearInterval(this.polling)
}
Does anyone finde the mistake?
Did I understand the polling wrong?
Greetings,
Matthias
The time value that you want to display needs to be a data / computed property so that it's reactive and Vue can track it. Concise way to do it:
export default {
data() {
return {
interval: null,
time: null
}
},
beforeDestroy() {
// prevent memory leak
clearInterval(this.interval)
},
created() {
// update the time every second
this.interval = setInterval(() => {
// Concise way to format time according to system locale.
// In my case this returns "3:48:00 am"
this.time = Intl.DateTimeFormat(navigator.language, {
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
}).format()
}, 1000)
}
}

Vuejs: listen to props changes and use it

I am developing a project using Vue JS and I need to watch the props changes and call it inside a <span>.
I have used watch() and it shows that the props values are assigned.
But when I call it inside the <span> the value is not showing.
props: ['verifyText', 'verifyValue', 'profileId', 'logged', 'verifyType', 'status'],
watch: {
verifyText: function () { // watch it
this.verify_text = this.verifyText;
},
verifyValue: function () {
this.verify_value = this.verifyValue;
},
verifyType: function () {
this.verify_type = this.verifyType;
}
},
data() {
return {
verify_type: this.verifyType,
verify_text: this.verifyText,
verify_value: this.verifyValue,
}
},
//using inside span
<span>{{verify_text}}</span>
Receive and insert new data that changes from 'watch'
Try this.
props: ['verifyText', 'verifyValue', 'profileId', 'logged', 'verifyType', 'status'],
watch: {
verifyText: function (new_value) {
this.verify_text = new_value;
}
},
data() {
return {
verify_text: this.verifyText,
}
},
//using inside span
<span>{{verify_text}}</span>
I solved this issue by watching the verify_text in the parent component.
'verify_text': function (value) {
this.verify_text = value;
},
Same for the verify_type and verify_value
Thank you all for replying.

Vue.js | Filters is not return

I have a problem.
I am posting a category id with http post. status is returning a data that is true. I want to return with the value count variable from the back. But count does not go back. Return in function does not work. the value in the function does not return from the outside.
category-index -> View
<td>{{category.id | count}}</td>
Controller File
/**
* #Access(admin=true)
* #Route(methods="POST")
* #Request({"id": "integer"}, csrf=true)
*/
public function countAction($id){
return ['status' => 'yes'];
}
Vue File
filters: {
count: function(data){
var count = '';
this.$http.post('/admin/api/dpnblog/category/count' , {id:data} , function(success){
count = success.status;
}).catch(function(error){
console.log('error')
})
return count;
}
}
But not working :(
Thank you guys.
Note: Since you're using <td> it implies that you have a whole table of these; you might want to consider getting them all at once to reduce the amount of back-end calls.
Filters are meant for simple in-place string modifications like formatting etc.
Consider using a method to fetch this instead.
template
<td>{{ categoryCount }}</td>
script
data() {
return {
categoryCount: ''
}
},
created() {
this.categoryCount = this.fetchCategoryCount()
},
methods: {
async fetchCategoryCount() {
try {
const response = await this.$http.post('/admin/api/dpnblog/category/count', {id: this.category.id})
return response.status;
} catch(error) {
console.error('error')
}
}
}
view
<td>{{count}}</td>
vue
data() {
return {
count: '',
}
},
mounted() {
// or in any other Controller, and set your id this function
this.countFunc()
},
methods: {
countFunc: function(data) {
this.$http
.post('/admin/api/dpnblog/category/count', { id: data }, function(
success,
) {
// update view
this.count = success.status
})
.catch(function(error) {
console.log('error')
})
},
},

VueJS and lodash, filtered array displays empty unless main array is utilized in template

My mixin:
export default {
data() {
return {
charges: [],
catCharges: [],
offenses: ['Class I Offenses', 'Class II Offenses', 'Class III Offenses', 'Class IV Offense']
}
},
methods: {
getCharges() {
axios.get('admin/charges').then((response) => {
this.charges = response.data;
for(let offense = 1; offense <= this.offenses.length; offense++) {
this.catCharges[offense - 1] = this.chargesAtOffense(offense);
}
});
},
chargesAtOffense(offense) {
return _.filter(this.charges, { offense_level: offense });
}
},
created() {
this.getCharges();
}
};
Fetching data works, the array 'charges' gets populated with the following:
After populating the array, I start looping over the offenses array and filter all 'charges' from the main array into the 'catCharges' array, so all offenses are split into 4 separated arrays in that array.
Chrome's developer tools shows the array just fine and the charges are properly filtered.
This is my component:
<template>
<div>
<h1>Total charges: {{charges.length}}</h1>
<h1>Total offense categories: {{catCharges.length}}</h1>
<div v-for="(charges, offenseIdx) in catCharges">
{{charges}}
</div>
</div>
</template>
<script>
import chargesMixin from '../mixins/chargesMixin';
export default {
mixins: [chargesMixin],
data() {
return {
}
},
methods: {
},
computed: {
},
mounted() {
console.log('Disciplinary Segregation mounted.')
}
}
</script>
It uses the mixin provided above, and IT works and shows the catCharges array properly, HOWEVER when I remove the following line from the template:
<h1>Total charges: {{charges.length}}</h1>
The catCharges array is displayed as EMPTY, why do I need to use the charges array too along with the filtered array? This is driving me crazy.
I also tried the following method in the mixin which also causes the same issue:
chargesAtOffense(offense) {
var newCharges = [];
for(var i = 0; i < this.charges.length; i++) {
if(this.charges[i].offense_level != offense) continue;
const cloned = _.clone(this.charges[i]);
newCharges.push(cloned);
}
return newCharges;
}
I think your use case is linked to the reactivity system of VueJS.
https://v2.vuejs.org/v2/guide/reactivity.html
If you delete the line
<h1>Total charges: {{charges.length}}</h1>
you tell to VueJS to refresh your template only on catCharges get / set.
catCharges is an array, and so it's not as 'reactive' as a simple variable.
If you read precisely https://v2.vuejs.org/v2/guide/list.html#Caveats, prefer use a push on your catCharges to explain correctly to Vue that your array has changed.
I'll try this code :
getCharges() {
axios.get('admin/charges').then((response) => {
this.charges = response.data;
for(let offense = 1; offense <= this.offenses.length; offense++) {
this.catCharges.push(this.chargesAtOffense(offense));
}
});
},
Hope this will solve your problem.

Two-way filter updating on the fly | Vue.js

How one can do custom two-way filter for model, updating on the fly in Vue.js.
The following code example from docs works on input blur. But I need it work on keypress.
Vue.filter('currencyDisplay', {
read: function(val) {
return '$'+val.toFixed(2)
},
write: function(val, oldVal) {
var number = +val.replace(/[^\d.]/g, '')
return isNaN(number) ? 0 : parseFloat(number.toFixed(2))
}
})
Many thanks in advance for any help!
You can apply a filter to a Vue data property by creating a computed property with a get and set method that fire the read and write methods of the filter, respectively:
data() {
return {
foo: 0,
}
},
computed: {
filteredFoo: {
get() {
return Vue.filter('currencyDisplay').read(this.foo);
},
set(value) {
this.foo = Vue.filter('currencyDisplay').write(value);
}
}
}
Here's a working fiddle.