I have 2 components in my project where I tried create query based search filter
- PostsList component:
JavaScript
x
64
64
1
<template>
2
<div>
3
<PostFilter @change-filter="setFilters" />
4
<h3>Active filters</h3>
5
<pre>{{ activeFilters }}</pre>
6
<h3>Updated filters</h3>
7
<pre>{{ updatedFilters }}</pre>
8
</div>
9
</template>
10
<script>
11
import PostFilter from "../../components/posts/PostFilter.vue";
12
export default {
13
components: {
14
PostFilter,
15
},
16
data() {
17
return {
18
updatedFilters: {},
19
activeFilters: {
20
category: "",
21
query: "",
22
perPage: 5,
23
page: 1,
24
},
25
};
26
},
27
28
methods: {
29
setFilters(updatedFilters) {
30
console.log("Active filters");
31
console.log(this.activeFilters);
32
33
console.log("Updated filters");
34
console.log(updatedFilters);
35
36
this.$router.push({ query: updatedFilters });
37
if (this.$route.query.page) {
38
updatedFilters.page = 1;
39
}
40
this.activeFilters = updatedFilters;
41
},
42
objectEquals(obj1, obj2) {
43
for (var i in obj1) {
44
// eslint-disable-next-line
45
if (obj1.hasOwnProperty(i)) {
46
// eslint-disable-next-line
47
if (!obj2.hasOwnProperty(i)) return false;
48
if (obj1[i] !== obj2[i]) return false;
49
}
50
}
51
for (var j in obj2) {
52
// eslint-disable-next-line
53
if (obj2.hasOwnProperty(j)) {
54
// eslint-disable-next-line
55
if (!obj1.hasOwnProperty(j)) return false;
56
if (obj1[j] !== obj2[j]) return false;
57
}
58
}
59
return true;
60
},
61
},
62
};
63
</script>
64
- PostFilter component:
JavaScript
1
137
137
1
<template>
2
<div>
3
<select class="category" v-model="filters.category" name="category">
4
<option value="" selected>All categories</option>
5
<option
6
v-for="(category, index) in categories"
7
:key="index"
8
:value="category.id"
9
>
10
{{ category.title }}
11
</option>
12
</select>
13
<input
14
class="search"
15
v-model="filters.query"
16
type="search"
17
name="query"
18
placeholder="Search..."
19
/>
20
<select class="perPage" v-model="filters.perPage" name="perPage">
21
<option value="5">5 items / page</option>
22
<option value="10">10 items / page</option>
23
<option value="15">15 items / page</option>
24
<option value="20">20 items / page</option>
25
</select>
26
</div>
27
</template>
28
29
<script>
30
export default {
31
emits: ["change-filter"],
32
33
created() {
34
const query = this.$route.query;
35
if (
36
query &&
37
Object.keys(query).length > 0 &&
38
query.constructor === Object &&
39
this.hasFilterKeys(query)
40
) {
41
this.filters = { this.filters, this.$route.query };
42
}
43
this.fecthCategories();
44
},
45
data() {
46
return {
47
filters: {
48
category: "",
49
query: "",
50
perPage: 5,
51
},
52
awaitingSearch: false,
53
categories: [],
54
};
55
},
56
watch: {
57
"filters.category": function (currentValue, oldValue) {
58
if (oldValue !== currentValue) {
59
this.emitFilters();
60
}
61
},
62
"filters.query": function (currentValue, oldValue) {
63
// eslint-disable-next-line
64
if (oldValue != currentValue) {
65
if (!this.awaitingSearch) {
66
setTimeout(() => {
67
this.emitFilters();
68
this.awaitingSearch = false;
69
}, 1000);
70
}
71
this.awaitingSearch = true;
72
}
73
},
74
"filters.perPage": function (currentValue, oldValue) {
75
if (oldValue !== currentValue) {
76
this.emitFilters();
77
}
78
},
79
},
80
methods: {
81
emitFilters() {
82
let cleanFilters = this.cleanObject(this.filters);
83
this.$emit("change-filter", cleanFilters);
84
},
85
cleanObject(obj) {
86
for (var propName in obj) {
87
if (
88
obj[propName] === null ||
89
obj[propName] === undefined ||
90
obj[propName] === ""
91
) {
92
delete obj[propName];
93
}
94
}
95
return obj;
96
},
97
async fecthCategories() {
98
this.categories = [
99
{
100
id: 1,
101
title: "Anatomy",
102
},
103
{
104
id: 2,
105
title: "Bialogy",
106
},
107
{
108
id: 3,
109
title: "Algebra",
110
},
111
{
112
id: 4,
113
title: "Chemistry",
114
},
115
{
116
id: 5,
117
title: "Computer science",
118
},
119
{
120
id: 6,
121
title: "English",
122
},
123
];
124
},
125
hasFilterKeys(obj) {
126
for (const key in this.filters) {
127
// eslint-disable-next-line
128
if (obj.hasOwnProperty(key) && obj[key] != "") {
129
return true;
130
}
131
}
132
return false;
133
},
134
},
135
};
136
</script>
137
I must send one API request when filters is change/update. But why I get same values in activeFilters
and in coming filters from method setFilters()
of PostsList component on everytime?
Why I lose old value of activeFilters
before set new values in my case?
You can see here real working example
Also here example video
JavaScript
1
1
1
<blockquote class="imgur-embed-pub" lang="en" data-id="a/Y4gauRM" ><a href="//imgur.com/a/Y4gauRM">Same object values on search</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
Advertisement
Answer
The object references in chrome developer console is “alive”.
Consider this example:
JavaScript
1
4
1
let x = {a: 'b'}
2
console.log("Active filters", x);
3
x.a = 'c';
4
this will output:
JavaScript
1
2
1
Active filters {a: "c"}
2
instead of Active filters {a: "b"}
You can use the spread operator to create a new object as value of activeFilters
in your example to see different values:
JavaScript
1
2
1
this.activeFilters = {updatedFilters};
2