Search code examples
arraysangulartypescriptdecrement

Angular decrement value in array


I try to decrement a value in my array, but I can't get it to work. My array data contains attributes and everytime a method gets clicked, I call that value from a service and increment it in the array object. The getter is equal to amountCounter.

My main problem is that whenever I try to remove an array object, my amountCounter won't also decrement the value which it had before, but the array object gets removed.

I also put two pictures to better clarify my problem, thank you so much for every help.

app.component.html

<h2>Add values of my service into array:</h2>
<p>Array:</p>
<p>Total: {{amountCounter}}</p>

<div *ngFor="let item of data, let i = index;">
  <span>ID: {{item.id}}</span>
  <span>Title: {{item.title}}</span>
  <span (click)="removeElement(i, item.amountCounter)" class="material-icons">
    close
    </span>
</div>

app.component.ts

export class AppComponent {
  clickEventsubscription: Subscription

  ngOnInit() {
  }

  id: number;
  title: String;
  amountCounter: number;
  data: any = [];

  constructor(private share: ShareDataService) {
    this.clickEventsubscription = this.share.getClickEvent().subscribe(() => {
      this.initialize();
    })
  }

  removeElement(id: number, counter: number) {
    this.data.splice(id, 1);
    this.amountCounter -= counter //In that line I can't get it to work that my attribute decrements
    console.log("before" + this.amountCounter);
    console.log("after:" + counter);
  }

  initialize() {
    this.id = this.share.getId();
    this.title = this.share.getTitle();
    this.amountCounter = this.share.getAmountCounter();

    const newData = {
      id: this.id,
      title: this.title,
      amountCounter: this.amountCounter
    };

    this.data.push(newData);
    console.log(this.data);
  }
}

share-data.service.ts

export class ShareDataService {
  private subject = new Subject<any>();

  title: String;
  id: number;
  amountCounter: number;

  getId() {
    return this.id;
  }

  getTitle() {
    return this.title;
  }

  getAmountCounter(){
    return this.amountCounter;
  }

  sendClickEvent() {
    this.subject.next();
  }

  getClickEvent(): Observable<any> {
    return this.subject.asObservable();
  }

}

That is how my array looks before ID 1 is clicked

That is how my array looks after I clicked at "X", but it decrements wrong

Thank you so much!


Solution

  • Not sure if this is the behavior you are after but generally this method will calculate the sum of the array values

      getTotalAmount(): number {
        return this.data.reduce((acc, item) => acc + item.amount, 0);
      }
    

    The main issue I found very difficult to figure out is that you have amountCounter in [share-data.service, dialog.component, app.component]

    I suppose you want to add new items using dialog.component with different amount values.

    Here you add new item to your 'data' array, the values for single item comes from share service which was updated in your dialog.component

      initialize() {
        console.log("initialize");
        const id = this.share.getId();
        const title = this.share.getTitle();
        const amount = this.share.getAmount();
    
        const newData = {
          id,
          title,
          amount
        };
    
        this.data.push(newData);
      }
    

    To summarize the flow:

    • in dialog.component you update field values in share-data.service clickMe() method
    • that method will trigger a method in app.component called initialize which will add the new item to the this.data array.
    • if you click on item (to remove it) splice will do it, and Angular will refresh the Total calling the getTotalAmount method

    Working Stackblitz.