Well, i know there are a ton of questions about this exact problem, but even after reading some of them, i can't solve my problem. I tried the solution with the changeDetectionRef, but either i am doing it wrong, or it just doesn't work in my case.
To my problem: I am making a budget book, adding transactions and stuff, everything was doing great until i added a balance overview, which shows the overall balance on the account and the change that is going to be applied in the month. The balance is sent from the parent(budget-book.component) to the child (day.component) in a ngFor directive. I see, that the problem i got is, that the same value is sent to each child, received, changed and sent to the next child afterwards. I tried making a array in the parent, where each balanceChange is saved and instead sending the sum of the previous days, but this didn't work out either. I was also thinking about making an observable.
budget-book.component.html
[...]
<ul class="days">
<app-day (addEvent)="addTransaction($event)" (removeEvent)="removeTransaction($event)" (balanceEvent)="updateBalance($event)"
*ngFor="let day of days; index as i" [date]="sendDate(this.date.getFullYear(), this.date.getMonth(), i + 1)"
[transactions]="getTransactions(i)" [balance]="balance"></app-day>
</ul>
[...]
budget-book.component.ts
[...]
balance: number;
ngOnInit(): void {
[...]
this.balance = 0;
}
[...]
updateBalance(balanceChange: number) {
this.balance += balanceChange;
}
day.component.html
<div class="header-balance-container">
<span [class.positive-number]="balance + balanceChange >= 0" [class.negative-number]="balance + balanceChange < 0" class="balance">{{balance + balanceChange | currency: 'EUR'}}</span>
<span [class.positive-number]="balanceChange >= 0" [class.negative-number]="balanceChange < 0 " class="difference" >{{balanceChange | currency: 'EUR'}}</span>
</div>
day.component.ts
@Input() balance: number;
balanceChange: number;
@Output() balanceEvent = new EventEmitter<number>();
ngOnChanges(): void {
this.balanceChange = 0;
if (this.transactions) {
this.transactions.forEach((transaction: Transaction) => {
this.balanceChange += transaction.value;
});
}
this.pushBalance();
// here is where i tried adding the changeDetectionRef
}
[...]
pushBalance() {
this.balanceEvent.emit(this.balanceChange);
}
I am on this problem since days and can't figure out, how to resolve. I'd be happy, if someone here could explain me, what i am missing and what my solution perspectives are.
EDIT:
A Service did it for me, for those interested in my stupidity, something simple as this solved the problem, which bothered me for days.
import {Injectable} from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class BalanceService {
balanceActivities: number[];
constructor() {
}
setBalances(dayCount: number) {
this.balanceActivities = new Array(dayCount);
}
addBalance(day: number, balanceActivity: number) {
this.balanceActivities[day] = balanceActivity;
}
getBalanceToDate(day: number) {
let balance = 0;
this.balanceActivities.forEach((balanceActivity, index) => {
balance += balanceActivity;
if (index >= day) {
return balance;
}
});
return balance;
}
getBalance() {
let balance = 0;
this.balanceActivities.forEach((balanceActivity, index) => {
balance += balanceActivity;
});
return balance;
}
}
You can try to use DoCheck:
class MyComponent implements OnInit, DoCheck {
private _balance: number = 0;
public balance: number;
ngOnInit(): void {
}
ngDoCheck(): void {
this.balance = this._balance;
}
updateBalance(balanceChange: number) {
this._balance += balanceChange;
}
}
But it doesn't seem like a very good solution. Depending on the task, you can use a service that will store the total balance, and you will not need to add it to the input / output.