1

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.

3
  • 1
    Using map() is the wrong tool for the job. It always returns a new array which is always truthy. Try some() or find(). Also this.search.toLower is invalid Commented Jan 3, 2021 at 12:33
  • 1
    Also, in your data ingredient is a string but you're trying to access it as an object in the code. Try changing it to ing.ingredient.toLowerCase().includes(this.search.toLowerCase()). Commented Jan 3, 2021 at 12:34
  • So you're saying that the || condition is correct? like i should just change map to find ? Commented Jan 3, 2021 at 12:44

2 Answers 2

1

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>

Sign up to request clarification or add additional context in comments.

Comments

1

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)

1 Comment

didn't really work but i did upvote for your effort ;) thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.