Reputation: 4287
I have a cart service in my Angular App and i was trying to make a plus minus quantity button on each item on the list when it has been added to the cart, when an item is firstly added to cart it's quantity is 1 and then the user by pressing +- can change it's quantity, the issue is that when i change the quantity to 3 and then i'm going to cart page and deleting that item, by going back to products page and by pressing "add to cart" it's setting the item with the quantity of 3 instead of 1 even if it has been deleted from the cart.
Here is my code:
CartService.ts:
addToCart(plu: Plu): void {
this.carrello.plu.push(product);
this.cartTotal(); // function which save the cart to localstorage
}
getQta(plu: Plu): number { // getting qta to be set if the cart exist in products list
const index = this.carrello.plu.indexOf(plu);
if (index !== -1) {
return this.carrello.plu[index].qta;
}
return 0;
}
updateQta(plu: Plu, qta: number): void {
const index = this.carrello.plu.indexOf(plu);
const oldQta = this.carrello.plu[index].qta;
const newQta = oldQta + qta;
if (newQta === 0){ // if quantity is 0 removing object from cart array
this.carrello.plu.splice(index);
this.cartTotal();
return;
}
this.carrello.plu[index].qta = newQta; // else updating it with new quantity
this.cartTotal();
}
Then my HTML where i call those method looks like this
<div *ngFor="let plu of plus">
<button
class="btn btn-block btn-primary"
[hidden]="getQta(plu) !== 0" // if never added to cart product show button Add to cart
(click)="addToCart(plu, $event)"
>
Aggiungi al carrello
</button>
<div
class="input-group"
[hidden]="getQta(plu) === 0" // else showing +- buttons for quantity
>
<div class="input-group-prepend">
<button class="btn btn-primary font-weight-bold" (click)="updateQta(plu, -1)">
-
</button>
</div>
<input
type="number"
class="form-control text-center"
disabled
[min]="plu.um === 'PZ' ? 1 : 0.001"
[step]="plu.um === 'PZ' ? 1 : 0.001"
[value]="
plu.um != 'PZ'
? (getQta(plu) | number: '1.3-3':'en-US')
: getQta(plu)
"
/>
<div class="input-group-append">
<button class="btn btn-primary font-weight-bold" (click)="updateQta(plu, 1)">
+
</button>
</div>
</div>
</div>
</div>
Then the methods are just recreated in ProductComponent.ts like this to be recalled:
addToCart(plu: Plu, event: Event): any {
event.preventDefault();
event.stopPropagation();
this.cartService.addToCart(plu);
this.showToast();
}
updateQta(plu: Plu, qta: number): void {
this.cartService.updateQta(plu, qta);
}
getQta(plu: Plu): number {
return this.cartService.getQta(plu);
}
But once the product has been removed from the CART page and i'm going back to Product list the original object of each Plu to which i changed the quantity has it as quantity instead of 1 so i actually see "Add to cart button" but once clicked it will show last selected quantity as it has been set to original object...
EDIT:
Here is a small example of my ProductComponent with cart service, as you could see once the item is added to cart, and added again (if item exist in cart service i'm adding qta instead of pushing it again to the array) the qta of the added item is even changing
Upvotes: 0
Views: 59
Reputation: 3588
I see what is the problem with your solution. The issue is that you are adding to a collection (the carrelo array) an object reference instead of a new instance of the object.
So the thing that happens is that the first time when you hit add you are adding a product with {qta:1 , id:1}
to the carrelo array, after that each time after that when you add product, you are looking (and finding) a product with the same id
but actually this product is exactly the same one as the one passed from the addProduct
function (both of them are references pointing to the same value), which means that you will be doubling it's qta
.
Here is a stackblitz with a solution, please go through the comments inside the cart.service
.
** Be careful with passing thing by reference
Upvotes: 1