0

I have multiple buttons on one page, "Add to cart" buttons where each button has a unique id attribute.

I want to hide a particular button when the user clicks on it.

The issue:

What's happening currently is that when a user clicks on a button 1 it hides, then clicks on button 2 it hides but on the same time it shows button 1

The expected behavior:

When the user clicks on button 1 it should hide and keep hiding even after clicking on button 2

P.S. the information of the buttons (products) gets added to an array.

Current code:

Html:

<div *ngFor="let product of products; let i = index">
<div *ngIf="hideButton != i" [attr.id]="i" class="addButton" (click)="addToCart(product, i)">ADD</div>
</div>

JS

addToCart(itemDetails, index) {
  this.hideButton = index;
}

4 Answers 4

3

You need an array of hidden buttons and you need to add the index to that array:

JS:

// at the top
hiddenButtons = [];

addToCart(itemDetails, index) {
  this.hiddenButtons.push(index);
}

HTML:

<div *ngFor="let product of products; let i = index">
<div *ngIf="hiddenButton.indexOf(i) === -1" [attr.id]="i" class="addButton" (click)="addToCart(product, i)">ADD</div>
</div>
Sign up to request clarification or add additional context in comments.

2 Comments

IMO hiding the implementation of the hiddenButton array at template level would be better. Consider a isHidden(i) or isHidden(product) method to be implemented.
@Jota.Toledo: Agreed
1

If you have a cart to which products are being added, you can look in the cart to check whether the product already exists in it, and use that to decide whether to display the ADD button.

If your product objects can have more properties to them, you can do away with indexes completely.

HTML

<div *ngFor="let product of products">
    <div *ngIf="productInCart(product)" [attr.id]="product.id" class="addButton" (click)="addToCart(product)">ADD</div>
</div>

JS

productInCart(product) {
    return this.products.findIndex(p => p.id==product.id)!=-1;
}
addToCart(product) {
    this.products.push(product);
}

Comments

0
<div *ngFor="let product of products; let i = index">
<div *ngIf="!product.isHidden" [attr.id]="i" class="addButton" (click)="addToCart(product, i)">ADD</div>
</div>

In component

 addToCart(itemDetails, index) {
  itemDetails.isHidden = true;
  this.products[index] = itemDetails;
 }

Logic behind this is to create a new property in product when it clicked for add to cart. Initially there will be no property with name isHidden. SO, it will return undefined and undefined will treat as false.

Comments

0

I would suggest the following:

<div *ngFor="let product of products; let i = index">
<div *ngIf="!isInCart(product)" [attr.id]="i" class="addButton" (click)="addToCart(product, i)">ADD</div>
</div>

private hiddenProducts = new Set<FooProduct>();
products: FooProduct[] = [];    

loadProducts(){
   this.products = // some value
   hiddenProducts = new Set<FooProduct>();
}

isInCart(product: FooProduct): boolean {
   return this.hiddenProducts.has(product);
}

addToCart(product: FooProduct, index: number){
    // optional: check if the element is already added?
    this.hiddenProducts.add(product);
    // rest of your addToCart logic
}

Why using a set instead of a simple array? Performance: access time is constant.

Why not use the index as identifier? Weak against list mutations (filter, reorder, etc)

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.