I have a component with an Add button that will go to the database, add a new record, then update the observable's data. The function to add the new record is a Promise that resolves once the new record has been added. While the component is reaching out to the database, I'd like to hide the Add button until the new record has been added. The template and component look roughly as follows:
Template:
<table>
...
</table>
<button (click)="addRow()" *ngIf="!addingRow">Add New</button>
Component Class (typescript):
export class AuctionComponent {
addingRow: boolean = false;
addRow() {
this.addingRow=true;
console.log('Adding Row');
this.salesSvc.addBid()
.then(()=> {
this.addingRow = false;
console.log('finished');
});
}
}
The promise to add the new record resolves in roughly one second. This is what I would think would happen:
- Click on Add Button
- {button disappears}
- "Adding Row" shows up in the console
- {wait a second for the promise to resolve}
- {button reappears}
- "finished" shows up in the console
Here is what is actually happening:
- Click on Add Button
- "Adding Row" shows up in the console
- {wait for a second for the promise to resolve}
- "finished" shows up in the console
- {button disappears briefly & reappears}
I've tried using ngZone.run(), ChangeDetectorRef .markForCheck() & .detectChanges(), and setTimeout(). I've also played around with ChangeDetectionStrategy of Default & OnPush. What am I missing?
Update
So the promise is reaching out and saving the data to firebase. Something with having to do with resolving the promise in firebase seems to be holding this up.
I changed the component to just test the promise part of it:
export class AuctionComponent {
addingRow: boolean = false;
addRow() {
this.addingRow=true;
console.log('Adding Row');
// this.salesSvc.addBid()
this.promise()
.then(()=> {
this.addingRow = false;
console.log('finished');
});
}
promise() {
return new Promise((resolve, reject) => {
setTimeout(resolve, 2000);
});
}
}
Doing this makes the button behave just like I anticipated.
The addBid method in the service looks like the following (this.af is AngularFire):
addBid(sale: ISale) {
return this.af.database.list(`sales/${sale.year}/bids`)
.push({lot: null, price: 0, description: ''});
}
So I thought that maybe something is happening with the firebase flavor of promise, so I wrapped the whole thing in my own promise:
addBid(sale: ISale) {
return new Promise((resolve, reject) => {
this.af.database.list(`sales/${sale.year}/bids`)
.push({lot: null, price: 0, description: ''})
.then(() => resolve())
.catch(() => reject());
});
}
But again, I'm still getting the delayed response. Is there something in firebase/angularfire2 that's causing the repaint to not happen?