How to combine multiple filters in Vue.js - vuejs2

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

Related

getters not reactive in vuex

I have following store defined:
state: () => ({
infoPackCreationData: null,
infoPackCreationTab: null,
}),
getters: {
infoPackImage(state: any) {
return state.infoPackCreationTab && state.infoPackCreationTab.infopackContents
? state.infoPackCreationTab.infopackContents.filter((item: any) => item.type === "IMAGE")
: [];
}
},
mutations: {
setImageData(state:any, infopackImageData: any) {
state.infoPackCreationTab.infopackContents.filter((item: any) => {if(item.type === "IMAGE")
item = infopackImageData
console.log(item , 'this is items');
return item})
}
},
actions: {
setImageData(context: any, payload: any) {
context.commit('setImageData', payload)
}
}
and in my component I am using the computed to get the imageList:
computed: {
...mapGetters("creationStore", ["infoPackImage"]),
imageList: {
get() {
return this.infoPackImage ?? [];
},
set(value) {
this.$store.dispatch('creationStore/setImageData', value);
}
}
},
The problem is I want to edit a value of the imageList by index using draggable libarary,
but imageList does not act reactive and it just move the image and not showing the other image in the previous index:
async imageChange(e) {
this.loading = true
let newIndex = e.moved.newIndex;
let prevOrder = this.imageList[newIndex - 1]?.order ?? 0
let nextOrder = this.imageList[newIndex + 1]?.order ?? 0
const changeImageOrder = new InfopackImageService();
try {
return await changeImageOrder.putImageApi(this.$route.params.infopackId,
this.$route.params.tabId,
e.moved.element.id, {
title: e.moved.element.title,
infopackAssetRef: e.moved.element.infopackAssetRef,
order: nextOrder,
previousOrder: prevOrder,
}).then((res) => {
let image = {}
let infopackAsset = e.moved.element.infopackAsset
image = {...res, infopackAsset};
Vue.set(this.imageList, newIndex , image)
this.loading = false
return this.imageList
});
} catch (e) {
console.log(e, 'this is put error for tab change')
}
},
Array.prototype.filter doesn't modify an array in-place, it returns a new array. So this mutation isn't ever changing any state:
mutations: {
setImageData(state:any, infopackImageData: any) {
state.infoPackCreationTab.infopackContents.filter((item: any) => {if(item.type === "IMAGE")
item = infopackImageData
console.log(item , 'this is items');
return item})
}
},
So, if you intend to change state.infoPackCreationTab.infopackContents, you'll need to assign the result of filter():
mutations: {
setImageData(state:any, infopackImageData: any) {
state.infoPackCreationTab.infopackContents = state.infoPackCreationTab.infopackContents.filter(...)
However, since state.infoPackCreationTab did not have an infopackContents property during initialization, it will not be reactive unless you use Vue.set() or just replace the whole infoPackCreationTab object with a new one (see: Vuex on reactive mutations):
mutations: {
setImageData(state:any, infopackImageData: any) {
state.infoPackCreationTab = {
...state.infoPackCreationTab,
infopackContents: state.infoPackCreationTab.infopackContents.filter(...)
};

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

Try to call the vuex getter in watch

I'm trying to call a Vuex getter in the component watch.
But it tells me that it is undefined what is not.
So i try to return the getter in the computed object but still doesn t work.
name: "FreeTalk",
computed: {
...mapGetters(['getCharacter','getResultStatus', 'getFreeTalkText', 'getResult', 'freeTalkResult', 'getFreeTalkNoNative', 'getFreeTalkMedium','getFreeTalkNative']),
progressStatus() {
return this.getResult.progress
},
getStatus() {
return this.getResultStatus
}
},
watch: {
progressStatus: (val) => {
if (val == 100) {
this.status = this.getStatus()
if (this.getStatus === 0) {
this.outputText = this.getFreeTalkNoNative.result;
} else if (this.getStatus === 1) {
this.outputText = this.getFreeTalkMedium;
} else if (this.getStatus === 2) {
this.outputText = this.getFreeTalkNative;
}
}
}
},
data() {
return {
outputText: '',
ready: false,
isRecordDone: false,
status: -1
}
}
}

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

feeding row data to ag-grid vue component

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();
},