2

i have this functions that adds more objects to an array, but the problem that i am facing is that if I have a key value exists in the array it still adds that key value, but I don't want to add it if exists already. This is what I have so far

 onCheckRecipe(e) {
    if (e.detail.checked === true) {
      let tickedRecipe = e.detail.value;
      let foundRecipeIngredients = [];
      let foundRecipe;
      this.loadedRecipes.filter(function (el) {
        if (el._id === tickedRecipe) {
          el.ingredients.map((elm) => {
            foundRecipe = elm;
            foundRecipeIngredients.push(foundRecipe);
          });
        }
      });
      this.groceryListUpdated = foundRecipeIngredients;
      this.groceryListDefault = this.groceryListDefault.concat(
        this.groceryListUpdated
      );
    }
  }

and in the console i receive smth like this:

(12) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {name: "", quantity: ""}
1: {_id: "5f64ac1eb227fea1f63a5ca3", name: "avocado", quantity: "50g"}
2: {_id: "5f64ac1eb227fea1f63a5ca4", name: "lemon juice", quantity: "5g"}
3: {_id: "5f64ac1eb227fea1f63a5ca5", name: "small mozzarella pearls", quantity: "70g"}
4: {_id: "5f64ac1eb227fea1f63a5c9e", name: "almond flour", quantity: "10g"}
5: {_id: "5f64ac1eb227fea1f63a5c9f", name: "egg", quantity: "10g"}
6: {_id: "5f64ac1eb227fea1f63a5ca0", name: "unsalted butter", quantity: "30g"}
7: {_id: "5f64ac1eb227fea1f63a5ca1", name: "peanut butter", quantity: "50g"}
8: {_id: "5f64ac1eb227fea1f63a5c99", name: "chia seeds", quantity: "10g"}
9: {_id: "5f64ac1eb227fea1f63a5c9a", name: "cherries", quantity: "15g"}
10: {_id: "5f64ac1eb227fea1f63a5c9b", name: "honey", quantity: "30g"}
11: {_id: "5f64ac1eb227fea1f63a5c9c", name: "almond flour", quantity: "10g"}
length: 12
__proto__: Array(0)

what I want to do is to not add eg: almond flour twice if it exists already, but just the quantity. I've tried a lot of methods, but nothing seems to work. If you guys have any idea I. would really appreciate it.

3
  • If e.detail.value is the id, it will not work b/c both "almond flour" have different ids Commented Sep 18, 2020 at 14:29
  • 2
    Consider editing the code above to constitute a minimal reproducible example suitable for dropping into a standalone IDE like The TypeScript Playground, where the only issue present is the one you're asking about. Commented Sep 18, 2020 at 14:33
  • @Emilien yes, you are right. I've checked it by name the instead, but still doesn't solve my issue... Commented Sep 18, 2020 at 14:36

2 Answers 2

2

First check if the item is present (by findIndex), if so, run a map and only increment the correct index.

If it's not present, well, just concat the new item.

Included below an example code. You will have to adapt to your needs, of course, but the idea is there.

const items = [{
  _id: "1",
  name: "avocado",
  quantity: 50
}, {
  _id: "2",
  name: "pasta",
  quantity: 60
}]

function addItems(newItem) {
  const index = items.findIndex((curItem) => curItem.name === newItem.name);
  if (index >= 0) {
    return items.map((curItem, curIndex) => {
      return index === curIndex ? {
          ...curItem,
          quantity: curItem.quantity + newItem.quantity
        } :
        curItem;
    });
  } else {
    return items.concat(newItem);
  }
}

console.log('Current items', items);

console.log('Adding a known item', addItems({
  _id: "1232",
  name: "avocado",
  quantity: 50
}));

console.log('Adding a new item', addItems({
  _id: "23232332",
  name: "meat",
  quantity: 50
}));

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

5 Comments

According to alex's info, the same ingredient can have a different _id, this is the case with almond flour 5f64ac1eb227fea1f63a5c9e - 5f64ac1eb227fea1f63a5c9c. If it's not a copy paste error on Alex's part, your function should filter by name and not _id.
And you don't need to map over the item list as you know the index you can directly access to it items[index].quantity += newItem.quantity and update the quantity attribute. I submit to you a update of your code :)
Hi! Yes, it was my mistake the filtering is by name and not _id indeed. Thank you for your help!
I have updated for the name filtering. And I usually don't suggest mutation on entry arguments, that's why I suggest for the map
Hi @alex, are you still needing help with your question? Otherwise, please accept the answer of it solves the issue
1

What I was looking for it's something likes this

onCheckRecipe(e) {
    if (e.detail.checked === true) {
      for (let recipe of this.loadedRecipes) {
        if (recipe.name === e.detail.value) {
          recipe.ingredients.forEach((eachIngredient) => {
            let matchedIng = this.groceryList.find(function (foundIng) {
              return foundIng.name === eachIngredient.name;
            });
            if (matchedIng) {
              matchedIng.quantity =
                matchedIng.quantity + eachIngredient.quantity;
            } else {
              this.groceryList.push(eachIngredient);
            }
          });
        }
      }

Comments

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.