Reputation: 21
I had a problem when I want to filter data with search box. I had to use code from this reference Vue2 Search in List received via Axios and still not working.
I want to get data from my local json file (that I put in public folders). Here's my db.json file:
{
"products": [
{
"id": 1,
"nama": "Skin10004",
"deskripsi": "Madagascar Centella Toning"
},
{
"id": 2,
"nama": "Some By Mi",
"deskripsi": "AHA-BHA-PHA 30 Days"
},
{
"id": 3,
"nama": "Avoskin",
"deskripsi": "Your Skin Bae Series Toner"
}
]
}
With axios, i'm successfully get all the data. But my problem is, my search box can't filter the data when user type on it. Here's my code in Products.vue:
// Here's my view code
<template>
<div>
<Navbar />
<div class="container">
<!-- Here's my search box but fail to filter the data-->
<div class="row mt-3">
<div class="col">
<div class="input-group mb-3">
<input
v-model="search"
type="search"
class="form-control"
placeholder="Cari disini .."
aria-label="Cari"
aria-describedby="basic-addon1"
@keyup="searchProducts"
/>
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">
<b-icon-search></b-icon-search>
</span>
</div>
</div>
</div>
</div>
<!-- Here's where my product display and success to display all data -->
<div class="row mb-4">
<div
class="col-md-4 mt-4"
v-for="product in products"
:key="product.id"
>
<CardProduct :product="product" />
</div>
</div>
</div>
</div>
</template>
<script src="https://unpkg.com/[email protected]"></script>
<script>
// Navbar and CardProduct is not the issue
import Navbar from "@/components/Navbar.vue";
import CardProduct from "@/components/CardProduct.vue";
import axios from "axios";
export default {
name: "Products",
components: {
Navbar,
CardProduct,
},
data() {
return {
products: [], // Where I store the data to display in view
search: null, // initialize search null
};
},
// Where I grab all the data in db.json
mounted() {
axios
.get("/db.json")
.then((response) => this.setProducts(response.data.products))
.catch((error) => console.log(error));
},
// Where I store the data to display in view
methods: {
setProducts(data) {
this.products = data;
},
},
// Here's my problem. Search can't filter the display data
computed: {
searchProducts: function () {
let searchTerm = (this.search || "").toLowerCase();
return this.products.filter(function (product) {
let nama = (product.nama || "").toLowerCase();
let deskripsi = (product.deskripsi || "").toLowerCase();
return (
nama.indexOf(searchTerm) > -1 || deskripsi.indexOf(searchTerm) > -1
);
});
},
},
created() {
setTimeout(() => (this.products = products), 500);
},
};
</script>
In console, i've got an error like this:
Thanks.
Upvotes: 0
Views: 831
Reputation: 138356
Uncaught ReferenceError: products is not defined
The error is likely in created()
, where products
doesn't seem to be defined anywhere:
export default {
created() {
setTimeout(() => (this.products = products), 500);
}, ^^^^^^^^
}
It doesn't look like you even need it, since your mounted()
hook populates this.products
. Just remove the created()
hook altogether.
[Vue warn]: Error in v-on handler: "TypeError: handler.apply is not a function"
This error is caused by your keyup
binding to the computed prop searchProducts
, which doesn't quite make sense. I suspect you actually want the displayed product list to be automatically filtered by the user's search term. The problem is the displayed product list loops through all products
, but it should be looping through searchProducts
:
<div
class="col-md-4 mt-4"
v-for="product in searchProducts"
:key="product.id"
>
<CardProduct :product="product" />
</div>
Just remove the @keyup
binding, and update the v-for
variable as shown above.
Upvotes: 1