Wrap http call in ionic loading to indicate blocking data fetch

pascalwhoop
curiouscaloo

--

Usually there are two types of data requests to the server. Those where the user has to wait and those in the background. While JavaScript is all about async calls these days, there are moments when we actually want to block a user to interact with the app. Ionic apps are no exception and so I came of with this piece of code which I use in my ionic+firebase app.

Code and explanation below the gif…

Basically I have one service which handles all my backend requests to my server. I have several convenience functions defined which only take very few arguments and are exposed to my UI components. Each of those functions has an additional flag called “blocking”. If this is true, the service returns the observable but also subscribes itself to it. It additionally wraps the call in a showLoading() and hideLoading() which blocks the user interaction until the call is complete

object(opts?:any, blocking?:boolean) {
if (blocking) this.l.showLoading(this.nc);
let obs = this.db.object(opts);
//hide loading on first answer from server and unsubscribe
let dispo = obs.subscribe(res=> {
//hack. sometimes this gets called synchronously which is annoying because dispo is not yet set..
if (blocking) this.l.hideLoading();
dispo.unsubscribe();

}, err=> {
if (blocking) this.l.hideLoading();
});

return obs;
}

The showLoading(nc : NavController) and hideLoading() functions then display the loading overlay. In case you’re wondering: What about multiple async calls? Well the implemented code keeps track of the show and hide calls and counts up / down

The full UI helper Component looks like this:

import {Loading, NavController, Toast} from "ionic-angular";
import {Injectable} from "@angular/core";


@Injectable()
export class FeedbackHelper {

constructor(){
this.count = 0;
}

l:Loading;
count:number;

showLoading(navCtrl:NavController) {

this.count++;
//increase requester count by one and if already over 0, return

if (this.count-1 || this.l) return;
//count was 0, we create a loading and show it.
this.l = Loading.create({
content: "loading ..."
});
navCtrl.present(this.l);
console.log("show loading");
}

hideLoading() {
this.count < 1 ? this.count = 0 : --this.count;
if (!this.count && this.l) {
this.l.dismiss();
this.l = null;
console.log("hide loading ");
}
}

}

Full code repository is on Github: ESN-Couchsurfing

Looking for something like this in Angular Material? Read this post

--

--

pascalwhoop
curiouscaloo

Software Developer, Tech enthusiast, student, board sports and food lover