Using LoadingController in Ionic 4 — waiting for API response
For me it was really hard to make LoadingController work in Ionic 4 and I couldn’t find decent guide how to implement it so I decided to share my way of doing it. I wanted to display loading indicator while I’m waiting for my API response.
First we will import LoadingController in a file where we want to use it.
book.page.ts
import {LoadingController} from '@ionic/angular';
Then pass it to our constructor
constructor(public loadingController: LoadingController) { }
Maybe you are using service to fetch your API response or you are doing it directly in the book.page.ts file http.get(myApi).subscribe() but the principle is the same. You have a function for getting data and populating your book array with it so you can finally show it to user. We can put all loading indicator logic with it too and it is probably the easiest way. Things start getting complicated when we want to separate logic.
books: any;ngOnInit() {
this.fetchBooks();
}async function fetchBooks() {
const loading = await this.loadingController.create({
message: 'Please wait...'
});
loading.present(); this.bookService.getBooks().subscribe(res => {
this.books = res;
loading.dismiss();
});
}
Now this is where most people make mistake. They will try something like this.
async fetchBooks() {
const loading = await this.getLoadingIndicator();
this.bookService.getBooks().subscribe(res => {
this.books = res;
loading.dismiss();
});
}
async getLoadingIndicator() {
const loading = await this.loadingController.create({
message: 'Please wait...'
}); return await loading.present(); // case 1
// or maybe
return loading.present(); // case 2
}
We could add duration of loading indicator in the loadingController.create() method like duration: 2000 but we want to be able to dismiss indicator when our response is ready so that is not very useful.
In the “Case 1”, we are calling present() method on our instance of loading controller which is returning Promise and when it shows the indicator, Promise will be resolved and it will return nothing (undefined). So when we try doing loading.dismiss() we are actually trying to use dismiss method on undefined and of course nothing will happen.
In the “Case 2”, we are returning Promise so we can’t use methods on it and if we try to await it, we are going back to “Case 1” and getting undefined.
To dismiss indicator we need instance of our created loadingController which is actually <ion-loading> element if we try logging it in console.
async getLoadingIndicator() {
const loading = await this.loadingController.create({
message: 'Please wait...'
});
loading.present();
return loading;
}
With this approach, first we are waiting for our indicator to be created and saving it to loading variable. After it has been created, we can display it with present() method. Lastly, we are returning instance of created loadingController itself.
I hope I saved you some time of unnecessary frustrations :)