Scenario :
On the left side of the screen, all unpaid bills are displayed. When a user clicks on a bill, its details appear on the right side. Upon clicking the pay button, the bill is marked as paid and should no longer be visible on the left side. This cycle continues for each bill.
Challenge :
I successfully paid a bill and it disappeared from the left side. However, when I attempt to click on the next bill on the left side, an error occurs.
Runtime Error ExpressionChangedAfterItHasBeenCheckedError: The expression has changed after being checked. Previous value: 'true'. Current value: 'false'.
Screencast :
https://i.sstatic.net/8SAbd.gif
Code :
bill-settlement.ts
@IonicPage()
@Component({
selector: 'page-bill-settlement',
templateUrl: 'bill-settlement.html',
})
export class BillSettlement {
billItem: BillDetail
updateItem: boolean
...
onBillSelected(billData: BillDetail) {
this.billItem = billData
}
isUpdate(updateData: boolean) {
this.updateItem = updateData
}
}
bill-settlement.html
...
<page-bill-list (BillSelected)="onBillSelected($event)" [updateItem]="updateItem"></page-bill-list>
...
<page-bill-details (isUpdate)="isUpdate($event)" [billItem]="billItem"></page-bill-details>
bill-list.ts
@IonicPage()
@Component({
selector: 'page-bill-list',
templateUrl: 'bill-list.html',
})
export class BillList {
billItems: BillDetail[] = []
billItem = new BillDetail()
@Input() updateItem: boolean
@Output() BillSelected: EventEmitter<BillDetail> = new EventEmitter<BillDetail>()
constructor(...) {
this.billSrv.getBills()
.subscribe(data => {
this.billItems = data
})
}
ngOnChanges(updateItem: boolean) {
if (this.updateItem == true) {
this.billSrv.getBills()
.subscribe(data => {
this.billItems = data
})
}
}
getBillDetails(item: BillDetail) {
this.BillSelected.emit(item)
}
}
bill-list.html
<ion-buttons>
<button ion-button *ngFor="let item of billItems" (click)="getBillDetails(item)">Bill {{item.BillNo}}</button>
</ion-buttons>
bill-details.ts
@IonicPage()
@Component({
selector: 'page-bill-details',
templateUrl: 'bill-details.html',
})
export class BillDetails {
...
@Input() billItem: BillDetail
@Output() isUpdate: EventEmitter<boolean> = new EventEmitter<boolean>()
...
ngOnChanges(billItem: BillDetail) {
this.isUpdate.emit(false) //if this part is commented
//the bills are paid but the left side is not reloaded from the second time
}
settleBill() {
...
this.billSrv.settleBill(...).subscribe(
data => {
if (data) {
this.isUpdate.emit(true) //so the bill list is reloaded
}
else {
...
}
}
)
}
}