feeding row data to ag-grid vue component - vue.js

In all the ag-grid-vue examples, data of rows are generated in the component's method of createRowData(), which is simple but not realistic.
I want to see an example in which row-data are provided to ag-grid vue component from the parent Vue instance.
If there's such information, please let me know.

I found a way by using Veux. Here's an example.
Appication.
let gridRows = {
state: {
rowData: []
},
mutations: {
push(state, rows) {
while( 0 < rows.length ){
state.rowData.unshift(rows.pop());
}
},
getters: {
rowData: state => {
let rows = state.rowData;
return state.rowData;
}
}
};
let store = new Vuex.Store(gridRows);
let app01 = new Vue({
el: '#app',
store,
render: h => h(DynamicComponentExample)
});
let rowData = [];
for (var i=0; i < 15; i++) {
rowData.unshift({
row: "Row " + i,
value: i,
currency: i + Number(Math.random().toFixed(2))
});
}
store.commit('push', rowData);
Component (modification to DynamicComponentExample.vue)
data () {
return {
gridOptions: null,
columnDefs: null
//rowData: null
}
},
computed: {
rowData(){
return this.$store.getters['rowData'];
}
},
beforeMount() {
...
//this.createRowData();
this.initColumnDefs();
},

Related

Insert Many to Many Data into Shopware 6 Database using the Administration

I have created a plugin in the adminstration and I want to insert the manyToMany products with vehicles into Shopware 6 database. From the code below I am trying to insert '92961afbc50e4380b3af86b257630ade' into the 'product_id' column of the 'vehicles_product' table :
import template from './sw-vehicles-import.html.twig';
const { Component, Mixin } = Shopware;
Component.register('sw-vehicles-import', {
template,
inject: ['importExport', 'repositoryFactory', 'feature'],
mixins: [
Mixin.getByName('notification'),
],
metaInfo() {
return {
title: this.$createTitle()
};
},
data() {
return {
importFile: null,
repository: null,
entity: undefined,
};
},
computed: {
},
created() {
this.repository = this.repositoryFactory.create('vehicles');
},
methods: {
onStartProcess() {
this.entity = this.repository.create(Shopware.Context.api);
this.entity.categoryFilter = 'CategoryName';
this.entity.featureFilter = 'FeatureName';
this.entity.products.productId = '92961afbc50e4380b3af86b257630ade';
this.repository.save(this.entity, Shopware.Context.api);
}
}
});
The build process doesn't work, what am I doing wrong? Could you help me please ?
You need to create a new entity collection for the association if it doesn't exist yet.
const { EntityCollection } = Shopware.Data;
if (!this.entity.products) {
this.entity.products = new EntityCollection(
'/product',
'product',
Shopware.Context.api
);
}
const product = await this.repositoryFactory.create('product').get('92961afbc50e4380b3af86b257630ade', Shopware.Context.api);
this.entity.products.add(product);
this.repository.save(this.entity, Shopware.Context.api);

I'm getting the error in vue.js - Unexpected side effect in "filteredTeamsData" computed property

Unexpected side effect in "filteredTeamsData" computed property
I have imported the two JSON file
import seasonList from '../assets/data/season_list.json'
import team data from '../assets/data/match_team.json'
Code -
export default {
name: 'SeasonSplit',
components: {
TableElement,
},
data () {
return {
selected: '1',
teamData: teamData,
teamList: [],
seasonList: seasonList,
filteredData: [],
tableColumns: ['toss_wins', 'matches', 'wins', 'losses', 'pts']
}
},
computed: {
filteredTeamsData: function () {
this.dataArr = []
this.filteredData = []
this.teamList = []
teamData.forEach(element => {
if(element.season == seasonList[this.selected-1]){
this.filteredData.push(element)
this.teamList.push(element.team)
this.dataArr.push(element.wins)
}
})
// console.log(this.filteredData)
return this.dataArr
}
}
}
I'd do it as follows:
export default {
name: 'SeasonSplit',
components: {
TableElement,
},
data () {
let filteredData = [];
let teamList = [];
let dataArr = [];
teamData.forEach(element => {
if(element.season == seasonList[this.selected-1]){
filteredData.push(element)
teamList.push(element.team)
dataArr.push(element.wins)
}
});
return {
selected: '1',
teamData: teamData,
teamList: teamList ,
seasonList: seasonList,
filteredData: filteredData ,
tableColumns: ['toss_wins', 'matches', 'wins', 'losses', 'pts'],
filteredTeamsData: dataArr
}
}

How can I write this code to be more efficient

I am learning Vue.js and I am setting up a website where I am using LocalStorage to store data.
I wrote some code, which is a little clunky and very repetitive:
<script>
const app = new Vue({
el:'#app',
data:{
explosive_pullups_1: '',
explosive_pullups_2: '',
explosive_pullups_3: '',
tuck_front_raises_1: '',
tuck_front_raises_2: '',
tuck_front_raises_3: '',
},
mounted() {
if (localStorage.explosive_pullups_1) {
this.explosive_pullups_1 = localStorage.explosive_pullups_1;
}
if (localStorage.explosive_pullups_2) {
this.explosive_pullups_2 = localStorage.explosive_pullups_2;
}
if (localStorage.explosive_pullups_3) {
this.explosive_pullups_3 = localStorage.explosive_pullups_3;
}
if (localStorage.tuck_front_raises_1) {
this.tuck_front_raises_1 = localStorage.tuck_front_raises_1;
}
if (localStorage.tuck_front_raises_2) {
this.tuck_front_raises_2 = localStorage.tuck_front_raises_2;
}
if (localStorage.tuck_front_raises_3) {
this.tuck_front_raises_3 = localStorage.tuck_front_raises_3;
}
},
watch: {
explosive_pullups_1(pullups1) {
localStorage.explosive_pullups_1 = pullups1;
},
explosive_pullups_2(pullups2) {
localStorage.explosive_pullups_2 = pullups2;
},
explosive_pullups_3(pullups3) {
localStorage.explosive_pullups_3 = pullups3;
},
tuck_front_raises_1(tuck_front_raises1) {
localStorage.tuck_front_raises_1 = tuck_front_raises1;
},
tuck_front_raises_2(tuck_front_raises2) {
localStorage.tuck_front_raises_2 = tuck_front_raises2;
},
tuck_front_raises_3(tuck_front_raises3) {
localStorage.tuck_front_raises_3 = tuck_front_raises3;
},
}
})
</script>
I would like to know a way to write this code to be less repetitive.
You can put the exercise data into its own object, and save that to localStorage instead. E.g.:
<script>
const app = new Vue({
el:'#app',
data: {
exercises: {},
},
mounted() {
this.exercises = JSON.parse(localStorage.getItem("exercises"));
},
watch: {
exercises(newExerciseValues) {
localStorage.setItem("exercises", JSON.stringify(newExerciseValues));
},
}
})
</script>
If you really need to store and retrieve the individual exercises explicitly, I would recommend keeping the data in one exercises object, and simply use a for loop to check/set everything. Something like this:
[...]
watch: {
exercises(newExercises) {
const exercisesToCheck = [
'explosive_pullups_1',
'explosive_pullups_2',
'explosive_pullups_3',
'tuck_front_raises_1',
'tuck_front_raises_2',
'tuck_front_raises_3',
];
for (const exercise of exercisesToCheck) {
localStorage.setItem(exercise, this.exercises[exercise]);
}
},
},
[...]
On a side note, be very careful when working with objects in Vue. If you need to add a new exercise to the exercises object, avoid using this.exercises['new_exercise'] = newExercise. Instead, use Vue.set(this.exercises, 'new_exercise', newExercise). Check out the Vue docs for an explanation.

How to combine multiple filters in Vue.js

I would like to combine some filters in my Vue app:
app = new Vue({
el: '#app',
data: {
products: null,
productGroups: null,
productPackageWeights: null,
checkedProductGroupItems: [],
checkedProductPackageWeights: [],
},
created: function created() {
this.fetchData();
},
computed: {
productsFilter: function () {
return this.filterProductGroupItems;
}
},
methods: {
fetchData: function () {
var vm = this
axios.get([MY_JSON_FILE])
.then(function(response){
console.log(response.data.filter_data.product_package_weights);
vm.productPackageWeights = response.data.filter_data.product_package_weights;
vm.productGroups = response.data.filter_data.product_groups;
vm.products = response.data.products;
}).catch(function (error) {
alert('Het ophalen van de producten is niet gelukt');
});
},
filterProductGroupItems: function(data) {
if (this.checkedProductGroupItems.length == 0) return true;
return this.checkedProductGroupItems.includes(data.features.product_groups.value);
},
filterProductPackageWeights: function(data) {
if (this.checkedProductPackageWeights.length == 0) return true;
return this.checkedProductPackageWeights.includes(data.features.product_package_weights);
},
}
});
The code works only for the filterProductGroupItems. How can I combine the filterProductGroupItems and filterProductPackageWeights results in the computed productsFilter function? I'm also planning to make some more filter functions.
Please help
Thanks!
you can do this
computed: {
productsFilter: function () {
return [...this.filterProductGroupItems(), ...this.filterProductPackageWeights()];
}
},
or concat
computed: {
productsFilter: function () {
return this.filterProductGroupItems().concat(this.filterProductPackageWeights());
}
},
the problem may be that you could end up with an array that has [true, Obj, Obj ...] if one filter returns true, so you may want to change the filter to return an empty array
filterProductGroupItems: function(data) {
if (this.checkedProductGroupItems.length == 0) return [];
return this.checkedProductGroupItems.includes(data.features.product_groups.value);
},
filterProductPackageWeights: function(data) {
if (this.checkedProductPackageWeights.length == 0) return [];
return this.checkedProductPackageWeights.includes(data.features.product_package_weights);
},

vue.js $watch array of objects

mounted: function() {
this.$watch('things', function(){console.log('a thing changed')}, true);
}
things is an array of objects [{foo:1}, {foo:2}]
$watch detects when an object is added or removed, but not when values on an object are changed. How can I do that?
You should pass an object instead of boolean as options, so:
mounted: function () {
this.$watch('things', function () {
console.log('a thing changed')
}, {deep:true})
}
Or you could set the watcher into the vue instance like this:
new Vue({
...
watch: {
things: {
handler: function (val, oldVal) {
console.log('a thing changed')
},
deep: true
}
},
...
})
[demo]
There is a more simple way to watch an Array's items without having deep-watch: using computed values
{
el: "#app",
data () {
return {
list: [{a: 0}],
calls: 0,
changes: 0,
}
},
computed: {
copy () { return this.list.slice() },
},
watch: {
copy (a, b) {
this.calls ++
if (a.length !== b.length) return this.onChange()
for (let i=0; i<a.length; i++) {
if (a[i] !== b[i]) return this.onChange()
}
}
},
methods: {
onChange () {
console.log('change')
this.changes ++
},
addItem () { this.list.push({a: 0}) },
incrItem (i) { this.list[i].a ++ },
removeItem(i) { this.list.splice(i, 1) }
}
}
https://jsfiddle.net/aurelienlt89/x2kca57e/15/
The idea is to build a computed value copy that has exactly what we want to check. Computed values are magic and only put watchers on the properties that were actually read (here, the items of list read in list.slice()). The checks in the copy watcher are actually almost useless (except weird corner cases maybe) because computed values are already extremely precise.
If someone needs to get an item that was changed inside the array, please, check it:
JSFiddle Example
The post example code:
new Vue({
...
watch: {
things: {
handler: function (val, oldVal) {
var vm = this;
val.filter( function( p, idx ) {
return Object.keys(p).some( function( prop ) {
var diff = p[prop] !== vm.clonethings[idx][prop];
if(diff) {
p.changed = true;
}
})
});
},
deep: true
}
},
...
})
You can watch each element in an array or dictionary for change independently with $watch('arr.0', () => {}) or $watch('dict.keyName', () => {})
from https://v2.vuejs.org/v2/api/#vm-watch:
Note: when mutating (rather than replacing) an Object or an Array, the
old value will be the same as new value because they reference the
same Object/Array. Vue doesn’t keep a copy of the pre-mutate value.
However, you can iterate the dict/array and $watch each item independently. ie. $watch('foo.bar') - this watches changes in the property 'bar' of the object 'foo'.
In this example, we watch all items in arr_of_numbers, also 'foo' properties of all items in arr_of_objects:
mounted() {
this.arr_of_numbers.forEach( (index, val) => {
this.$watch(['arr_of_numbers', index].join('.'), (newVal, oldVal) => {
console.info("arr_of_numbers", newVal, oldVal);
});
});
for (let index in this.arr_of_objects) {
this.$watch(['arr_of_objects', index, 'foo'].join('.'), (newVal, oldVal) => {
console.info("arr_of_objects", this.arr_of_objects[index], newVal, oldVal);
});
}
},
data() {
return {
arr_of_numbers: [0, 1, 2, 3],
arr_of_objects: [{foo: 'foo'}, {foo:'bar'}]
}
}
If your intention is to render and array and watch for changes on rendered items, you can do this:
Create new Component:
const template = `<div hidden></div>`
export default {
template,
props: ['onChangeOf'],
emits: ['do'],
watch: {
onChangeOf: {
handler(changedItem) {
console.log('works')
this.$emit('do', changedItem)
},
deep: true
}
},
}
Register that component:
Vue.component('watcher', watcher)
Use it inside of your foreach rendering:
<tr v-for="food in $store.foods" :key="food.id">
<watcher :onChangeOf="food" #do="(change) => food.name = 'It works!!!'"></watcher>
</tr>