I have this array of recipes where each object is a specific recipe and each recipe has an array of ingredients and each ingredient it's an object made of _id name quantity. My problem added below if you guys have any idea why is this happening please let me know. I am struggling for 3 days...any advice would be really appreciated. Thanks a lot!
(3) [{…}, {…}, {…}]
0:
ingredients: Array(4)
0: {_id: "5f6628d0029e87e02c79ce0a", name: "chia", quantity: 10}
1: {_id: "5f6628d0029e87e02c79ce0b", name: "apple", quantity: 15}
2: {_id: "5f6628d0029e87e02c79ce0c", name: "honey", quantity: 30}
3: {_id: "5f6628d0029e87e02c79ce0d", name: "almond flour", quantity: 35}
length: 4
__proto__: Array(0)
name: "Coconut Chia Pudding"
__v: 0
_id: "5f6628d0029e87e02c79ce09"
__proto__: Object
1: {_id: "5f6628d0029e87e02c79ce0e", name: "Peanut Butter Cookies", ingredients: Array(4), __v: 0}
2: {_id: "5f6628d0029e87e02c79ce13", name: "Caprese Avocado Bowls", ingredients: Array(3), __v: 0}
length: 3
__proto__: Array(0)
What I have in UI it's a list with the above recipes which a user can tick and untick and after a recipe has been ticked its ingredients are showed into a list.
HTML
<ion-content>
<ion-grid>
<ion-row>
<ion-col>
<ion-list>
<ion-item
*ngFor="let recipe of loadedRecipes; let lastRecipe = last"
[ngClass]="{ 'last-recipe': lastRecipe }"
>
<ion-checkbox
(ionChange)="onCheckRecipe($event)"
value="{{recipe.name}}"
></ion-checkbox>
<ion-label>{{recipe.name}}</ion-label>
<ion-button
[routerLink]="['/','recipes','recipe-details', recipe._id]"
>></ion-button
>
</ion-item>
</ion-list>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<h6 class="ion-padding-start" *ngIf="groceryList.length > 0">
Grocery List
</h6>
<ion-list *ngIf="groceryList.length > 0">
<ion-item *ngFor="let ingredient of groceryList">
<ion-label>{{ingredient.name}}</ion-label>
<ion-note slot="end">{{ingredient.quantity}} g</ion-note>
</ion-item>
</ion-list>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
What I want to achieve (and I've done it below, but I have a bug) is when the user ticks a recipe its ingredients to be added into an array called groceryList and when unticks the recipe to remove the ingredients from my groceryList array. Also, if I have ticked 1 recipe and if the next one I am going to tick has the same ingredient as the one ticked before, just to increment that common ingredient quantity that already exists, and NOT to add it twice and if I want to untick a recipe to remove the uncommon ingredients and subtract the quantity of the common ingredient. I already managed to do it, BUT I have a big problem and I don't know where is coming from. at some point in UI if I tick and untick recipes and I tick the ones that have the same ingredient one after another it removes the common ingredient even though I still have a ticked recipe that has that ingredient. Again, if you guys have any idea why is this happening please let me know I would appreciate any advice you have
My TS
import { Component, OnInit } from "@angular/core";
import { Subscription } from "rxjs";
import { RecipesService } from "src/app/services/recipes.service";
@Component({
selector: "app-recipes",
templateUrl: "./recipes.page.html",
styleUrls: ["./recipes.page.scss"],
})
export class RecipesPage implements OnInit {
loadedRecipes: any;
private _recipesSub: Subscription;
constructor(private recipesService: RecipesService) {}
groceryList = [];
ngOnInit() {
this._recipesSub = this.recipesService.recipes.subscribe((receivedData) => {
this.loadedRecipes = receivedData;
});
}
onCheckRecipe(e) {
if (e.detail.checked === true) {
for (let recipe of this.loadedRecipes) {
console.log(this.loadedRecipes);
if (recipe.name === e.detail.value) {
for (let eachIngredient of recipe.ingredients) {
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);
}
}
}
}
} else {
for (let recipe of this.loadedRecipes) {
if (recipe.name === e.detail.value) {
for (let eachIngredient of recipe.ingredients) {
let matched = this.groceryList.find(function (foundIngre) {
return foundIngre.name === eachIngredient.name;
});
if (
matched.name === eachIngredient.name &&
matched._id === eachIngredient._id
) {
let index = this.groceryList.findIndex(
(x) => x._id === matched._id
);
this.groceryList.splice(index, 1);
} else {
matched.quantity = matched.quantity - eachIngredient.quantity;
}
}
}
}
}
}
ionViewWillEnter() {
this.recipesService.fetchRecipes().subscribe();
}
ngOnDestroy() {
if (this._recipesSub) this._recipesSub.unsubscribe();
}
}