Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

When I add new element to the array, new cost in cont registered

I learning Angular and I have first problem. My service look like this

import { Injectable } from '@angular/core';
import { COSTInterface } from './COSTSInterface'
import {Costs} from './mock-cost'

import { Observable, of } from 'rxjs'

@Injectable({
  providedIn: 'root'
})
export class CostService {

  getCosts(): Observable<COSTInterface[]> {
    return of(Costs);
  }

  getBalance(): Observable<number> {
    let balance = 0;
    this.getCosts().subscribe(costs => {
      for (const cost of costs) {
        if (cost.type === 'income') {
          balance += cost.cost;
        } else {
          balance -= cost.cost;
        }
      }
    });
    return of(balance)
  }

  add(element: COSTInterface): void {
    Costs.push(element)
  }

  getCount(): Observable<number>{
    return of(Costs.length);
  }
  constructor() { }
}

OK. I can add new element to the array

  profileForm = this.fb.group({
    id: [0],
    name: [''],
    type: [''],
    cost: [0]
  })
  count:number = 0;

  getCount() {
    this.costService.getCount().subscribe(count => {
      this.count = count + 1;
    })
  }
  onSubmit() {
    const newCost: COSTInterface = {
      id: this.count || 0, // Jeśli wartość jest null lub undefined, ustawiamy 0 jako domyślną wartość
      name: this.profileForm?.value.name || '',
      type: this.profileForm?.value.type || '',
      cost: this.profileForm?.value.cost || 0
    };

    this.costService.add(newCost)
  }
  constructor(private fb: FormBuilder, private costService: CostService){}

  ngOnInit(){
    this.getCount();
  }

But the balance is not calculated automatically when a new element is added.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Summary Component when I have the balance is very simple and looks like this

  balance:number = 0;

  getBalance(): void {
    this.costService.getBalance().subscribe(balance => {
      this.balance = balance;
    });
  }
 constructor(private costService: CostService){}
 ngOnInit() {
   this.getBalance();
 }

can guess where the problem is, but I have no idea how to solve it. Propably service’s method getBalance don’t know that we change array of costs but I don’t know how solve this problem.

How can I display new total cost after I add new element?

>Solution :

Your CostService.getBalance is not handling asynchronous events properly. Rewrite it this way:

  getBalance(): Observable<number> {
    return this.getCosts()
               .pipe(map(costs => {
      let balance = 0;
      for (const cost of costs) {
        if (cost.type === 'income') {
          balance += cost.cost;
        } else {
          balance -= cost.cost;
        }
      }
      return balance;
    }));
  }

It makes the "getBalance" return the correct balance amount. But it wouldn’t retrigger when a new cost is added. For this, you need BehaviorSubjects:

  private balance$: BehaviorSubject<number> = new BehaviorSubject(0); // 0 is default value)
  constructor(/*someStuff*/) {
    // init balance
    this.updateBalance();
  }

  getBalance(): Observable<number> {
    return this.balance$.asObservable();
  }

  private updateBalance() {
    return this.getCosts()
               .subscribe(costs => {
      let balance = 0;
      for (const cost of costs) {
        if (cost.type === 'income') {
          balance += cost.cost;
        } else {
          balance -= cost.cost;
        }
      }
      // triggers the event to all subscribers
      this.balance$.next(balance); 
    }));
  add(element: COSTInterface): void {
    Costs.push(element);
    this.updateBalance();
  }
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading