link1644 link1645 link1646 link1647 link1648 link1649 link1650 link1651 link1652 link1653 link1654 link1655 link1656 link1657 link1658 link1659 link1660 link1661 link1662 link1663 link1664 link1665 link1666 link1667 link1668 link1669 link1670 link1671 link1672 link1673 link1674 link1675 link1676 link1677 link1678 link1679 link1680 link1681 link1682 link1683 link1684 link1685 link1686 link1687 link1688 link1689 link1690 link1691 link1692 link1693 link1694 link1695 link1696 link1697 link1698 link1699 link1700 link1701 link1702 link1703 link1704 link1705 link1706 link1707 link1708 link1709 link1710 link1711 link1712 link1713 link1714 link1715 link1716 link1717 link1718 link1719 link1720 link1721 link1722 link1723 link1724 link1725 link1726 link1727 link1728 link1729 link1730 link1731 link1732 link1733 link1734 link1735 link1736 link1737 link1738 link1739 link1740 link1741 link1742 link1743 link1744 link1745 link1746 link1747 link1748 link1749 link1750 link1751 link1752 link1753 link1754 link1755 link1756 link1757 link1758 link1759 link1760 link1761 link1762 link1763 link1764 link1765 link1766 link1767 link1768 link1769 link1770 link1771 link1772 link1773 link1774 link1775 link1776 link1777 link1778 link1779 link1780

[Vue.js] VueJS default value for select not working

when tying to set a default value for a select in Vue.

<script src=”https://unpkg.com/vue"></script>

<div id=”app”>
<select v:model=”select”>
<option value=”1”>1</option>
<option value=”2”>2</option>
<option value=”3”>3</option>
</select>
</div>

<script>
new Vue({
el: ‘#app’,
data: {
select: ‘2’
}
})
<script>

I would expect the default value to be 2, but it is 1 ?

Here is a fiddle - https://jsfiddle.net/dqgsbw9o/

Solution :

the code is correct except for v:model. That should be v-model:

<select v-model=”select”>

updated fiddle

[Vue.js] How to outsource asyncData to Vuex Store?

I’m currently loading some data from firebase I wan’t to be server side rendered so it can be indexed for SEO in asyncData on a page.

asyncData() {
return firebase.firestore().collection(‘Programms’).get().then((querySnapshot) => {
const programms = [];
querySnapshot.forEach((doc) => {
const programm = doc.data();
programm.id = doc.id;
programms.push(programm)
})
return { programms: programms};
})

However I would like to convert this to my vuex store.

I know I could do this:

const actions = {
async nuxtServerInit({ commit }) {
firebase.firestore().collection(‘Programms’).onSnapshot((querySnapshot) => {
const programms = [];
querySnapshot.forEach((doc) => {
const programm = doc.data();
programm.id = doc.id;
programms.push(programm)
})
console.log(‘loaded Programms’, programms)

commit(‘setProgramms’, programms);
})
},
}

But this way the data will be loaded for every route in my app. I wan’t to load this data only in some pages where I also display it, so I don’t load it unnecessary.

How could I do this in Vuex?

Solution :

As @aldarund says, the fetch method is precisely what you want.

fetch ({ store, params }) {
return firebase.firestore().collection(‘Programms’).get().then((querySnapshot) => {
const programms = [];
querySnapshot.forEach((doc) => {
const programm = doc.data();
programm.id = doc.id;
programms.push(programm)
})
.then(() => {
store.commit(‘setPrograms’, programms)
})
}

See the docs here.

[Vue.js] Nuxt - I'm struggling with very slow axios requests in asyncData

nuxt: 2.4.5
@nuxtjs/axios: 5.4.1

I fetch data in asyncData and it lasts like 5s, it makes loading a page awfully long, it is related to axios request, when I do the same, but in method created instead of asyncData, everything is perfect.

I’ve tried to reinstall all dependencies and use older versions and the newest as well with the same result.

asyncData({ app: {$axios} }) {
// this is very slow
return $axios.get(‘/api/v1/advertisements’).then(() => {});
},

created() {
// this works perfect
this.$axios.get(‘/api/v1/advertisements’).then(() => {});
},

Axios requests should works the same when using in created and asyncData.

Solution :

They are working same. It means the api return data for 5 seconds, so u need to see what wrong with the api.

The difference between asyncData and created is that in asyncData nuxt will wait for request to be completed before rendering page, and in created it wont wait and just will render page and update it later with request result

[Vue.js] Async / Await Vuex

to call an action in created hook, wait until is done and in same hook to display the result. Is that possible?

I tried to put async / await in actions but doesn’t help.
This is the action property with the async function in the store:

actions: {
async FETCH_USER({commit}) {
await firebase.firestore().collection(‘test’).get().then(res => {
commit(‘FETCH_USER’, res.docs[0].data())
})
}
}

created() {
this.FETCH_USER()
console.log(this.GET_USER)
},
methods: {
…mapActions([
‘FETCH_USER’
]),
login() {
if(this.$refs.form.validate()) {
console.log(‘welcome’)
}
}
},
computed: {
…mapGetters([
‘GET_USER’
])
}

export default new Vuex.Store({
state: {
user: null
},
getters: {
GET_USER: state => state.user
},
mutations: {
FETCH_USER(state, user) {
state.user = user
}
},
actions: {
FETCH_USER({commit}) {
firebase.firestore().collection(‘test’).get().then(res => {
commit(‘FETCH_USER’, res.docs[0].data())
})
}
}
})

Solution :

async/await version

async FETCH_USER({ commit }) {
const res = await firebase.firestore().collection(‘test’).get()
const user = res.docs[0].data()
commit(‘FETCH_USER’, user)
return user
}

async created() {
// The action returns the user out of convenience
const user = await this.FETCH_USER()
console.log(user)

// — or –

// Access the user through the getter
await this.FETCH_USER()
console.log(this.GET_USER)
}

You need to await the action call because it is an async function.

Promise version

FETCH_USER({ commit }) {
return firebase.firestore().collection(‘test’).get().then(res => {
const user = res.docs[0].data()
commit(‘FETCH_USER’, user)
return user
})
}

created() {
this.FETCH_USER().then(user => {
console.log(user)
})

// — or –

this.FETCH_USER().then(() => {
console.log(this.GET_USER)
})
}

[Vue.js] How to access data outside the onclick function

I need to access my component’s data property (id[]) from within the onClick function of my Chart initialization object, but I get an undefined error when I try id[position]:

window.open(“/#/user/history/detail/“ + id[position], “_self”);

My data property:

data() {
return {
id: [1,2,3,4,5]
};
}

and onClick function:

mounted() {
this._chart = new Chart({

onClick: function(evt, array) {
if (array.length != 0) {
var position = array[0]._index;
console.log(position);
window.open(“/#/user/history/detail/“ + id[position], “_self”); //problem
} else {
console.log(“You selected the background!”);
}
}
})
}

Solution :

Use this when referring to a variable from the component’s data and props attribute.

So instead of:

window.open(“/#/user/history/detail/“ + id[position], “_self”);

Use:

window.open(“/#/user/history/detail/“ + this.id[position], “_self”);

Solution 2:

In onClick: function(evt, array) { }, this is the Chart instance. To bind the context to the vue.js instance, use an arrow function:

this._chart = new Chart({
onClick: (evt, array) => {

console.log(this.id[position])
}
)

updated fiddle

[Vue.js] Why does my array update when method called live but doesn't in unit tests?

there is a method called toggleSelect that adds and removes objects from an array called selectedItems. This works perfectly live in the browser.
It doesn’t seem to work during my unit test. Not clear why because I’m calling it directly from the component and passing it an argument. If I console.log() the item inside the method, it does display in the log correctly. The method runs, but the array never gets updated to verify that it works.

let items = [{
“ID”: “12345”,
“Name”: “Real Person”,
“Description”: “How a real person ought to be described”,
“Date”: “2015-04-12T04:24:49-07:00”,
“Amount”: 120.23
}]

const wrapper = shallowMount(DataTable, {
propsData: { items }
})

// toggle method directly on component
wrapper.vm.toggleSelect(items[0])

// verify that the array has been updated
console.log(DataTable.data().selectedItems)

The log shows an empty array just in the test.

Solution :

DataTable.data().selectedItems should be wrapper.vm.selectedItems.

The component instance’s data properties are also exposed on wrapper.vm, so you would access the instance’s current data directly by key:

expect(wrapper.vm.selectedItems).toContain(items[0])

[Vue.js] How can I filter the ${{ data }} object to only show specific values?

when using vue.js and dumping my data ${ data } and outputing this to the user, however, I would only like to display specific values. In this instance, to show everything but NOT Actions.

I would only like to show: Name, Description and Method.

{
“Name”: “”,
“Description”: “”,
“Actions”: [
{
“Actions”: “Microsoft.AAD/domainServices/oucontainer/write”
},
{
“Actions”: “Microsoft.AAD/domainServices/oucontainer/delete”
},
{
“Actions”: “Microsoft.AAD/domainServices/oucontainer/read”
}
],
“Method”: “a,b,c,d,”
}

Solution :

You can create a method which will do it for you.

let first create a method where I will be using spread syntax.Check this link as well.

https://codingexplained.com/coding/front-end/vue-js/working-with-methods-in-vue-js

new Vue({
el: ‘#app’,
data: {
message: ‘Hello Vue.js!’,
actions : [“this i it”, “abc”],
lovely: “asdf”

},
methods : {
getData : function(){
let {actions, …dataExceptAction} = this.$data;
return dataExceptAction;
}
}

})

Now I can simply use the getData method on my template

<div id=”app”>
<p>{ getData() }</p>
</div>

Working example of this is here
https://jsfiddle.net/3cy2roLp/45/

[Vue.js] Vue.js - Table gets updated but selected checkbox data does not

I’ve ran into a bug that I can’t seem to solve. there is a table with selectable rows. When a checkbox is checked, the amount column is summed up.

But, when the data in the table changes using a datepicker, the merchant total on the right and the amount in the selected checkboxes object do not update and reflect what is in the table.

Below are two images illustrating what’s happening.

Here is a codepen: https://codepen.io/anon/pen/NmKBjm

Solved the issue but I believe there’s a more optimal method using v-model but I just can’t get it to work. I’m basically fetching the data and then re-assigning the selected object with the data.

this.volume = response.data;

this.total = this.volume.reduce(function(p, n) {
return p + parseFloat(n.amount);
}, 0);

let merchants = this.selected.map(m => m.merchantName);
let filterMerchants = this.volume.filter(e => e ? merchants.includes(e.merchantName) : null);

this.selected = filterMerchants;
this.onCheckboxChange();

And here is my code.

<v-data-table v-model=”selected” id=”transactions-volume-table” :headers=”tableHeaders” :items=”volume” item-key=”merchantName” :loading=”loading” :search=”searchTable” hide-actions class=”elevation-1”>
<v-progress-linear slot=”progress” color=”blue” indeterminate></v-progress-linear>
<template v-slot:items=”props”>
<td><v-checkbox v-model=”props.selected” @change=”onCheckboxChange” primary hide-details></v-checkbox></td>
<td class=”text-xs-left”>{ props.item.divisionName }</td>
<td class=”text-xs-left”>{ props.item.merchantName }</td>
<td class=”text-xs-left”>{ props.item.amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, “,”) }</td>
</template>
</v-data-table>

data() {
return {
search: {
fromDate: new Date().toISOString().substr(0, 10),
toDate: new Date().toISOString().substr(0, 10)
},
fromDateModal: false,
toDateModal: false,
searchTable: ‘’,
loading: true,
volume: [],
total: null,
merchantTotal: 0,
tableHeaders: [{ text: ‘Select’, sortable: false },
{ text: ‘Division’, value: ‘divisionName’, sortable: true },
{ text: ‘Merchant’, value: ‘merchantName’, sortable: true },
{ text: ‘Amount ()’, value: ‘amount’, sortable: true }],
selected: []
}
}

onCheckboxChange() {
console.log(this.selected);
this.merchantTotal = this.selected.reduce(function(p, n) {
return p + parseFloat(n.amount);
}, 0);
}

Solution :

Sorry, my bad. Reformulation.

vue.js has a limitation in reactivity to detect changes in objects. That is the problem, you can not know when the volume array change because datepicker changes. You should use this.$set to detect the changes in objects (an array is an object).

Link: https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

This is a sample code:

<div id=”app”>
{ message[0] }
<button v-on:click=”change”>Change</button>
</div>

<script>
var app = new Vue({
el: ‘#app’,
data: {
message: [45,35,50]
},
methods: {
change: function () {
//this.$set(this.message, 0, 35);
message[0] = 35;
console.log(this.message);
}
}
});
</script>

uncomment the line commented and try, you will see the difference.

Solution 2:

You update the merchant total only if a checkbox changes. You should update the merchant total in case the dates change as well. Because the date change it does not trigger a checkbox to change event.

EDIT
No, because the checkbox change event only gets triggered when it changes(click on it or manually fired). the merchantTotal isn’t a computed property so it isn’t acting on anything. You can try and make it computed, actually it’s a computed action you are trying to mimic.

EDIT
Check this fiddle I created. Like the example everything is working around the selected rows. In cases the selected variable changes (after applied filters or toggle a checkbox on or of) it will re-computed the total. In my example I use products in stead of merchants, but in function it’s doing the same.

EDIT
Are you able to add a unique identifier foreach merchant in the dataset? Or you can create a ID based on 2 rows (division and merchantname). Its the only way around this is calculate the data via the volume (based on the selected merchant id or unique identifier, like I illustrated). Another way to do it is when data changes you unselect the merchants, but this is not really user friendly.

I thought it was a vue.js implementation problem, but I think the problem lies within the working of the datatable from Vuetify (in the situation).

[Vue.js] how to change type array object to format object without looping method in vue.js?

how to change type array object to format object without looping method in vue.js?

example:

// Data Array
data = [
{
id: 1,
token: ‘123’,
name: ‘name’,
contact: ‘lorem ipsum’,
},
{
id: 1,
token: ‘123’,
name: ‘name’,
contact: ‘lorem ipsum’,
},
]

to

// Format Object
{
id: ‘’,
token: ‘’,
identity: {
name: ‘’,
contact: ‘’
},
}

thanks

Solution :

Use map:

const data = [{
id: 1,
token: ‘123’,
name: ‘name’,
contact: ‘lorem ipsum’,
},
{
id: 1,
token: ‘123’,
name: ‘name’,
contact: ‘lorem ipsum’,
}
];

const newData = data.map(({ id, token, name, contact }) => ({
id,
token,
identity: {
name,
contact
}
}));

console.log(newData);
.as-console-wrapper { max-height: 100% !important; top: auto; }

[Vue.js] How to apply formatting to v-model value and remove formatting before commiting in store

I’m assigning a vueex store value to a v-model in a v-text-field.
This value is stored as an integer. Is there a way to simply format this value and let the user change it and remove formatting when he applies changes?

The format is ##:##:##
But the value is stored in seconds.

when using this approach: https://vuex.vuejs.org/guide/forms.html

Here’s how my store is built. I keep it simple:


mutations: {

updateSwimFtp (state, swimFtp) {
state.athlete.swimFtp = swimFtp
}

},

In my vue.js component, I use a computed attribute to get the value and store use it in the v-model. The formatting happens in the get() and the unformatring happens in the set().


<v-text-field
:label=”$vuetify.t(‘$vuetify.swimFtp’)”
:hint=”$vuetify.t(‘$vuetify.swimFtp’)”
mask=”time-with-seconds”
v-model=”swimFtp”
required>
</v-text-field>


computed: {
athlete() {
return this.$store.state.athlete
},

swimFtp: {
get () {
var date = new Date(null);
date.setSeconds(this.$store.state.athlete.swimFtp);
return date.toISOString().substr(11, 8);
},
set (value) {
var hoursInSecs = parseInt (String( this.$store.state.athlete.swimFtp ).substring(0, 2),10)*60*60;
var minsInSecs = parseInt (String( this.$store.state.athlete.swimFtp ).substring(3, 5),10)*60;
var secs = parseInt (String( this.$store.state.athlete.swimFtp ).substring(6, 8),10);
var _secsToStore = hoursInSecs+minsInSecs+secs;
this.$store.commit(‘updateSwimFtp’, _secsToStore);
}
},

},

The problem with this approach is that when the user clicks on back/delete key it calls the set() method. Since it’s two way binding approach, the value gets stored with wrong value and the get() is formating it again.

Is there a way to only use the return key event from the text field or is there an other aproach I should use?

Solution :

Finally got something working.

Simplified the store.js methods:

mutations: {
setSwimFtp (state, swimFtp) {
state.athlete.swimFtp = swimFtp
}
},

actions: {
//TODO post to server here
updateSwimFtp ({ commit }, value) {
commit(‘setSwimFtp’, value);
}
}

In my vue.js component, there is added to the text field an instruction to return the masked value. This will return the value with the mask.

<template>
<v-flex xs12 sm6 offset-sm3>
<form
lazy-validation
ref=”form”>
<v-text-field
:label=”$vuetify.t(‘$vuetify.swimFtp’)”
:hint=”$vuetify.t(‘$vuetify.swimFtp’)”
v-model=”swimFtp”
mask=”time-with-seconds”
return-masked-value=”true”
required>
</v-text-field>

<v-btn @click=”**submit**“>submit</v-btn>
<v-btn @click=”clear”>clear</v-btn>
</form>

</v-flex>
</template>

there is simplified the setter to store the masked value without trying to unformat the value. This fixes the flickering of the field when the user if modifying the value. Vue.js will react to every change and the get will show partial user input. So just store what’s in the field.

computed: {

swimFtp: {
get () {
var date = new Date(null);
var _val = String(this.$store.state.athlete.swimFtp);
if ( _val.includes(“:”) )
return this.$store.state.athlete.swimFtp;
else {
date.setSeconds(this.$store.state.athlete.swimFtp);
return date.toISOString().substr(11, 8);
}
},

set (value) {
this.$store.commit(‘setSwimFtp’, value);
}
}

},

And finally, at submit of the form, I remove the formatting to make sure the value is sent to the server database in seconds, not with a masked value.

methods: {

submit: function() {
var hoursInSecs = parseInt (String( this.$store.state.athlete.swimFtp ).substring(0, 2),10)*60*60;
var minsInSecs = parseInt (String( this.$store.state.athlete.swimFtp ).substring(3, 5),10)*60;
var secs = parseInt (String( this.$store.state.athlete.swimFtp ).substring(6, 8),10);
var _secsToStore = hoursInSecs+minsInSecs+secs;
this.$store.dispatch(‘updateSwimFtp’, _secsToStore)
},

},