I have two functions in my application that retrieves data from SQLite, However, function A loads faster than function B. I tried putting LoadingController but it doesn’t work. Once the page loads, function A has already been rendered in the view before the Loader even begins. Then once the Loader is dismissed, I have to wait 3 seconds before function B fully renders to my view.
So the flow is
Page loads -> Function A fully renders to view -> Loader.present() -> Loader.dismiss() -> (wait 3 seconds) Function B renders
I’m not sure if this has something to do with my database but I only have a couple of data. I even tested it on a new phone but it is still happening.
This is my code:
database.ts
getPastExpensesSavings() {
return this.database.executeSql("SELECT b.*, SUM(CASE WHEN es.type = 'expenses' AND es.date != strftime('%Y-%m-%d', DATE('now', 'localtime')) THEN 1 ELSE 0 END) number_of_expenses, IFNULL(SUM(CASE WHEN es.type='expenses' AND es.date != strftime('%Y-%m-%d', DATE('now', 'localtime')) THEN es.amount ELSE 0 END), 0) AS total_expenses, SUM(CASE WHEN es.type = 'savings' AND es.date != strftime('%Y-%m-%d', DATE('now', 'localtime')) THEN 1 ELSE 0 END) number_of_savings, IFNULL(SUM(CASE WHEN es.type='savings' AND b.budget_id Is NOT NULL AND es.date != strftime('%Y-%m-%d', DATE('now', 'localtime')) THEN es.amount ELSE 0 END), 0) AS total_savings, IFNULL(b.amount - (SUM(CASE WHEN es.type='expenses' AND es.date != strftime('%Y-%m-%d', DATE('now', 'localtime')) THEN es.amount ELSE 0 END) + SUM(CASE WHEN es.type='savings' AND b.budget_id IS NOT NULL AND es.date != strftime('%Y-%m-%d', DATE('now', 'localtime')) THEN es.amount ELSE 0 END)), b.amount) as remaining FROM budget AS b LEFT JOIN expenses_savings AS es ON b.budget_id = es.budget_id WHERE b.budget_id IS NOT NULL GROUP BY b.budget_id ORDER BY b.budget_id DESC", {})
.then(data => {
this.expenses_savings = [];
if(data.rows.length > 0) {
for(var i = 0; i < data.rows.length; i++) {
this.expenses_savings.push({
budget_id: data.rows.item(i).budget_id,
amount: data.rows.item(i).amount,
valid_from: data.rows.item(i).valid_from,
valid_to: data.rows.item(i).valid_to,
total_expenses: data.rows.item(i).total_expenses,
total_savings: data.rows.item(i).total_savings,
number_of_savings: data.rows.item(i).number_of_savings,
number_of_expenses: data.rows.item(i).number_of_expenses,
remaining: data.rows.item(i).remaining,
details: []
});
}
}
return this.expenses_savings;
}, err => {
return err;
})
}
getPastSavingsExpensesDetails() {
return this.database.executeSql("SELECT * FROM expenses_savings WHERE date != strftime('%Y-%m-%d', DATE('now', 'localtime')) AND budget_id IS NOT NULL ORDER BY date DESC, time DESC", {})
.then(res => {
this.expenses_savings_details = [];
if(res.rows.length > 0) {
for(var i = 0; i < res.rows.length; i++) {
this.expenses_savings_details.push({
budget_id: res.rows.item(i).budget_id,
type: res.rows.item(i).type,
category: res.rows.item(i).category,
title: res.rows.item(i).title,
date: res.rows.item(i).date,
time: res.rows.item(i).time,
datetime: res.rows.item(i).date + ' ' + res.rows.item(i).time,
amount: res.rows.item(i).amount,
note: res.rows.item(i).note,
image: res.rows.item(i).image
});
}
}
return this.expenses_savings_details;
}, err => {
return err;
})
}
page.ts
ionViewWillEnter() {
this.getPastExpensesSavings();
}
getPastExpensesSavingsDetails() {
this.dp.getPastSavingsExpensesDetails()
.then(data => {
this.pastExpensesSavingsDetails = data;
})
}
getPastExpensesSavings() {
this.dp.getPastExpensesSavings()
.then(data => {
let loading = this.loadingCtrl.create({
content: 'Loading data. Please wait...'
});
loading.present();
if(data.length == 0){
this.hasPastExpenses = false;
}else {
this.hasPastExpenses = true;
this.pastExpensesSavings = data;
this.dp.getPastSavingsExpensesDetails()
.then(data => {
this.pastExpensesSavingsDetails = data;
for(var es = 0; es < this.pastExpensesSavings.length; es++) {
for(var esd = 0; esd < this.pastExpensesSavingsDetails.length; esd++) {
if(this.pastExpensesSavings[es].budget_id == this.pastExpensesSavingsDetails[esd].budget_id) {
this.pastExpensesSavings[es].details.push(this.pastExpensesSavingsDetails[esd])
}
}
}
})
}
loading.dismiss();
})
}
page.html
<ion-list *ngFor="let item of pastExpensesSavings">
<accordion [list]="item"></accordion>
<div class="test" *ngIf="item.details.length > 0">
<ion-item *ngFor="let detail of item.details" (click)="showDetails(detail.expenses_savings_id)">
<ion-icon class="card-icon" item-start [name]="detail.type == 'expenses' ? 'trending-up' : 'cash' " [color]="detail.type == 'expenses' ? 'danger' : 'custom'"></ion-icon>
<h2>{{ detail.title }}</h2>
<p>{{ detail.amount | number:'.2-2' }}</p>
<p *ngIf="detail.type == 'expenses'" class="time-ago" item-end>Spent {{ detail.datetime | timeAgo }}</p>
<p *ngIf="detail.type == 'savings'" class="time-ago" item-end>Added {{ detail.datetime | timeAgo }}</p>
</ion-item>
</div>
<p text-center *ngIf="!item.details.length">No past records to show</p>
</ion-list>
Is there a way I can make sure the the Loader stays until the data are fully retrieved and ready for render?
Thank you very much!