(New to Vue.js) I fetch data from a get request to display calendar information. I want this to update every 5 minutes.
Nothing in the docs about auto reload - how would I go about implementing this? Do I use standard javascript within the file or something else?
My complete app.js below:
Vue.component('events', {
template: '#events-template',
data: function() {
return {
list: []
}
},
created: function() {
this.fetchEventsList();
},
methods: {
fetchEventsList: function() {
this.$http.get('events', function(events) {
this.list = events;
}).bind(this);
}
}
});
new Vue({
el: 'body',
});
No need to re-invent the wheel, window.setInterval() does the job pretty well
Vue.component('events', {
template: '#events-template',
data () {
return {
list: [],
timer: ''
}
},
created () {
this.fetchEventsList();
this.timer = setInterval(this.fetchEventsList, 300000);
},
methods: {
fetchEventsList () {
this.$http.get('events', (events) => {
this.list = events;
}).bind(this);
},
cancelAutoUpdate () {
clearInterval(this.timer);
}
},
beforeUnmount () {
this.cancelAutoUpdate();
}
});
new Vue({
el: 'body',
});
Related
I am creating undo/redo functionality in VueJS. I watch the settings and add a new element to an array of changes when the settings change. I also have a method for undo when the undo button is clicked.
However, when the button is clicked and the last setting is reverted, the settings are changed and the watch is fired again.
How can I prevent a new element being added to the array of changes if the settings changed but it was because the Undo button was clicked?
(function () {
var Admin = {};
Admin.init = function () {
};
var appData = {
settings: {
has_border: true,
leave_reviews: true,
has_questions: true
},
mutations: [],
mutationIndex: null,
undoDisabled: true,
redoDisabled: true
};
var app = new Vue({
el: '#app',
data: appData,
methods: {
undo: function() {
if (this.mutations[this.mutationIndex - 1]) {
let settings = JSON.parse(this.mutations[this.mutationIndex - 1]);
this.settings = settings;
this.mutationIndex = this.mutations.length - 1;
console.log (settings);
}
},
redo: function() {
}
},
computed: {
border_class: {
get: function () {
return this.settings.has_border ? ' rp-pwb' : ''
}
},
undo_class: {
get: function () {
return this.undoDisabled ? ' disabled' : ''
}
},
redo_class: {
get: function () {
return this.redoDisabled ? ' disabled' : ''
}
}
},
watch: {
undoDisabled: function () {
return this.mutations.length;
},
redoDisabled: function () {
return this.mutations.length;
},
settings: {
handler: function () {
let mutation = JSON.stringify(this.settings),
prevMutation = JSON.stringify(this.mutations[this.mutations.length-1]);
if (mutation !== prevMutation) {
this.mutations.push(mutation);
this.mutationIndex = this.mutations.length - 1;
this.undoDisabled = false;
}
},
deep: true
}
}
});
Admin.init();
})();
Since you make the changes with a button click, you can create a method to achieve your goal instead of using watchers.
methods: {
settings() {
// call this method from undo and redo methods if the conditions are met.
// move the watcher code here.
}
}
BTW,
If you don't use setter in computed properties, you don't need getters, so that is enough:
border_class() {
return this.settings.has_border ? ' rp-pwb' : ''
},
These watchers codes look belong to computed:
undoDisabled() {
return this.mutations.length;
},
redoDisabled() {
return this.mutations.length;
},
I am receiving data in JSON from PHP and I want to detect if JSON have changed on Javascript side, not template side. Does anybody have solution? I am attaching a code.
export default {
name: 'dashboard_invoices',
data() {
return {
invoices: [],
newInvoices: [],
}
},
methods: {
loadDataInterval: function() {
this.$http.get('http://127.0.0.1/pdaserwis-crm/api/vue/vue?action=order_table').then(function (response) {
this.newInvoices = response.data;
if(this.newInvoices != this.invoices) {
// alert('Dodano nowa fakture');
this.invoices = this.newInvoices;
}
})
},
loadData: function() {
this.$http.get('http://website.pl').then(function (response) {
this.invoices = response.data;
})
}
},
created: function () {
this.loadData();
setInterval(function () {
this.loadDataInterval();
}.bind(this), 3000);
}
}
I want to catch if invoices have changed and view appropriate alert for that.
The problem solved. It took to compare both arrays with deep-equal by watch handler.
watch: {
invoices: {
handler(val, oldVal)
{
if(!(deepEqual(val, oldVal))) {
console.log('elo');
}
}
}
}
I am new to Vue. I struggling and trying last half day not got any solution.
Here, I need to change todos text automatically based ajax response.
Using setInterval need to update vue instance and change HTML DOM as well.
When I update todo object, can't change the DOM automatically
<div id="app">
<ul>
<li v-for="question in todos.text">
{{ question.text }}
</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: function () {
return {
message: 'You loaded this page on ' + new Date().toLocaleString(),
todos:
{
Event: 'Event1',
text: [
{ text: 'Learn JavaScript1' },
{ text: 'Learn Vue1' },
{ text: 'Build something awesome1' }
]
}
}
},
mounted: function() {
setInterval(function () {
axios({
method: 'post',
url: 'test.php',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
}).then(response => {
console.log(response.data);
this.todos = response.data;
Vue.set(this, todos, response.data );
})
.catch(err => {
console.log(err);
});
}, 5000);
}
})
</script>
The scope of this is bound to Window instead of your Vue instance.
mounted: function() {
console.log(this); // Vue
setInternval(function() {
console.log(this); // Window
}, 1000);
setInterval(() => {
console.log(this); // Vue
}, 1000);
}
You had the right idea with your axios promises, .then(response => { .. }) in using the arrow function to preserve the scope of this but you didn't apply it to setInterval.
If for some reason you really like the look of setInterval(function() { .. }), or you need this to be the Window object, you can create a variable and assign it to this outside of the setInterval function.
mounted: function() {
const vThis = this; // Vue
setInterval(function() {
axios({..})
.then(response => {
vThis.todos = response.data;
console.log(this); // Window
console.log(vThis); // Vue
})
.catch(error => {
});
}, 5000);
}
I want to change the class of a component in VueJS after 2.5 seconds and I'm using this code:
const Header = {
template: `<header :class=hclass v-html="header"></header>`,
data () {
return {
hclass: 'off'
}
},
methods: {
changeVisibility () {
window.setTimeout(function () {
this.hclass = 'on'
console.log('Change to on!', this.hclass)
}, 2500)
}
},
computed: {
header () {
this.changeVisibility()
return store.state.header
}
}
}
While I see it in the console it says 'Change to on!', it never actually updates my class with 'on'!
Thank you for pointing to the right direction!
methods: {
changeVisibility () {
setTimeout(function () {
this.hclass = true
console.log('Change to on!', this.hclass)
}.bind(this), 5000)
}
}
I am trying to catch vue.js custom event within one component, but it's not catching. What's the problem?
myEventFunc: function() {
this.myEvent = true;
},
clickedFunc: function() {
this.clicked = true;
this.$emit('myevent');
}
JSFiddle Example: https://jsfiddle.net/ucean0rh/1/
I'm not sure if this is a Vue way of dealing with it, but it works in my JSFiddle. Simply call myEventFunc() from within clickedFunc:
new Vue({
el: "#app",
data: {
myEvent: false,
clicked: false,
},
methods: {
myEventFunc: function() {
this.myEvent = true;
},
clickedFunc: function() {
this.clicked = true;
this.myEventFunc();
this.$emit('myevent');
}
}
})