Reputation: 1126
So I have an array of objects that looks like this :
let medicines = [
{
id:3340,
name:nutraplus,
description:"some medicine",
ingredients: [{
ingredient:"glycerol"
},
{
ingredient:"Morphine"
}
]
},
{
id:3320,
name:Panadol,
description:"tablet",
ingredients: [{
ingredient:"Paracetamol"
},
{
ingredient:"Some stuff"
}
]
}
]
I want to to be able to filter by name and by ingredient name I have acheived the former by doing this :
computed: {
medicines() {
return this.$store.state.medicines.filter(med => {
//this.search is the what comes after typing in search bar
return med.name.toLowerCase().includes(this.search.toLowerCase())
})
},
}
Its vue.js so the computed() stuff anyways this works perfectly when searching by name however i also want to be able to search by ingredients from the same search bar. I tried something like this :
edicines() {
return this.$store.state.medicines.filter(med => {
return med.name.toLowerCase().includes(this.search.toLowerCase()) || med.ingredients.map(ing=>{
ing.ingredient.name.toLowerCase().includes(this.search.toLower)
})
})
}
But it didn't work. Any ideas on how to get this working? Thank you for your time.
Upvotes: 1
Views: 101
Reputation: 1361
Haven't used vue in the example, you just need to extract the logic behind the filtering that I have done (Simple JS filtering)
As example -
Try searching for 'Para' - It must return the entries with name/ingredient containing Para
Try searching for 'stuff' - It should return two entries (since both medicine in that array consist of 'some stuff' as ingredient)
let medicines = [{
id: 3340,
name: 'nutraplus',
description: "some medicine",
ingredients: [{
ingredient: "glycerol"
},
{
ingredient: "Morphine"
},
{
ingredient: "Some stuff"
}
]
},
{
id: 3320,
name: 'Panadol',
description: "tablet",
ingredients: [{
ingredient: "Paracetamol"
},
{
ingredient: "Some stuff"
}
]
},
{
id: 3311,
name: 'Amazin',
description: "tablet"
}
];
const form = document.querySelector('form')
form.addEventListener('submit', (e) => {
e.preventDefault();
const searchValue = form.searchText.value.toLowerCase();
const matchValue = medicines.filter(medicine => {
return medicine.name.toLowerCase().includes(searchValue) || (medicine.ingredients ? medicine.ingredients.filter(ingredientObj => {
return ingredientObj.ingredient.toLowerCase().includes(searchValue);
}).length > 0 : false);
});
document.querySelector('.result').textContent = JSON.stringify(matchValue, null, 4);
});
pre {
background: #c5c5c5;
}
<form>
<label for="searchText"></label>
<input type="text" id="searchText" name="searchText">
<button>Search</button>
</form>
<pre class='result'></pre>
Upvotes: 1
Reputation: 131
This should work.
let medicines = [
{
id:3340,
name:"nutraplus",
description:"some medicine",
ingredients: [{
ingredient:"glycerol"
},
{
ingredient:"Morphine"
}
]
},
{
id:3320,
name:"Panadol",
description:"tablet",
ingredients: [{
ingredient:"Paracetamol"
},
{
ingredient:"Some stuff"
}
]
}
];
const searchPhrase = "Paracetamol";
const filteredByName = medicines.filter((medicine) => {
return medicine.name.toLowerCase() === searchPhrase.toLowerCase();
});
const filteredByIngredient = medicines.filter((medicine) => {
return medicine.ingredients.some((item) => item.ingredient.toLowerCase() === searchPhrase.toLowerCase());
})
const result = [...filteredByName, ...filteredByIngredient];
console.log(result)
Upvotes: 1