I'm trying to make a custom http interceptor which will be used to handle loading and other additional functions. (handling loading for each request manually significantly increasing the amount of code).
The problem is: Loader is getting activated on each request, but loading.dismiss()
is not working.(Loading spinner keeps being active, no errors)
My config:
http interceptor:
@Injectable()
export class MyHttpWrapper extends Http {
private loading: any;
constructor(connectionBackend: ConnectionBackend, requestOptions: RequestOptions,private loadingCtrl: LoadingController) {
super(connectionBackend, requestOptions);
}
public get(url: string, options?: RequestOptionsArgs): Observable<Response> {
this.showLoader();
return super.get(url, this.getRequestOptionArgs(options))
.finally<Response>(() => {
this.hideLoader();
});
}
public post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
return super.post(url, body, options);
}
public put(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
return super.put(url, body, options);
}
public delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
return super.delete(url, options);
}
private getRequestOptionArgs(options?: RequestOptionsArgs) : RequestOptionsArgs {
if (options == null) {
options = new RequestOptions();
}
if (options.headers == null) {
options.headers = new Headers();
}
options.headers.append('Content-Type', 'application/json');
return options;
}
private showLoader() {
if(!this.loading){
this.loading = this.loadingCtrl.create({
dismissOnPageChange: true
});
}
this.loading.present();
console.log('show loader')
}
private hideLoader() {
console.log('hide loader')
console.log(this.loading)
this.loading.dismiss();
}
}
app.module.ts
export function httpInterceptorFactory(xhrBackend: XHRBackend, requestOptions: RequestOptions, loadingCtrl: LoadingController) {
return new MyHttpWrapper(xhrBackend, requestOptions, loadingCtrl);
}
@NgModule({
declarations: [
MyApp
],
imports: [
BrowserModule,
HttpModule,
IonicModule.forRoot(MyApp),
IonicStorageModule.forRoot()
],
bootstrap: [IonicApp],
entryComponents: [
MyApp
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
{provide: APP_CONFIG, useValue: AppConfig},
{
provide: Http,
useFactory: httpInterceptorFactory,
deps: [XHRBackend, RequestOptions, LoadingController]
}
]
})
export class AppModule {}
UPDATE:
tried to add simple service(and use it in MyHttpWrapper
), doesn't change anything, same problem.
@Injectable()
export class LoadingService {
private loading:any;
constructor(private loadingCtrl: LoadingController) {
}
show() {
if(!this.loading){
this.loading = this.loadingCtrl.create({
dismissOnPageChange: true
});
}
this.loading.present();
}
hide() {
if (this.loading) {
this.loading.dismiss();
}
}
}
I'm using the below custom HTTP interceptor on my Ionic 3 apps
This is the loader.ts
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import { LoadingController } from 'ionic-angular';
@Injectable()
export class LoaderProvider {
constructor(public http: Http, public loadingCtrl: LoadingController) {
}
loading: any = this.loadingCtrl.create({
content: "Please wait..."
})
show() {
this.loading.present();
}
hide() {
this.loading.dismiss();
}
}
This is the HTTP interceptor
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/Rx';
import { LoaderProvider } from '../loader/loader';
/*
Ionic 3 HTTP interceptor
Author: iSanjayAchar (@iSanjayAchar) <[email protected]>
*/
@Injectable()
export class httpService {
baseUrl: string = 'https://yourbaseurl.in'
constructor(public http: Http, private loader: LoaderProvider) {
}
get(url) {
this.loader.show();
return this.http.get(this.baseUrl + url)
.map(resp => resp.json())
.finally(() => {
this.loader.hide();
});
}
post(url, body) {
this.loader.show();
return this.http.post(this.baseUrl + url, body)
.map(resp => resp.json())
.finally(() => {
this.loader.hide();
});
}
put(url, body) {
this.loader.show();
return this.http.put(this.baseUrl + url, body)
.map(resp => resp.json())
.finally(() => {
this.loader.hide();
});
}
delete(url) {
this.loader.show();
return this.http.delete(this.baseUrl + url)
.map(resp => resp.json())
.finally(() => {
this.loader.hide();
});
}
patch(url, body) {
this.loader.show();
return this.http.patch(this.baseUrl + url, body)
.map(resp => resp.json())
.finally(() => {
this.loader.hide();
});
}
}
Now finally import this instead of http everywhere, example below
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Http, Headers, RequestOptions } from '@angular/http';
import { ToastController } from 'ionic-angular';
import 'rxjs/add/operator/map';
import { AlertController } from 'ionic-angular';
import { httpService } from '../../providers/http/http';
/**
* Generated class for the LoginPage page.
*
* See http://ionicframework.com/docs/components/#navigation for more info
* on Ionic pages and navigation.
*/
@IonicPage()
@Component({
selector: 'page-login',
templateUrl: 'login.html',
})
export class LoginPage {
isLoginIn: boolean = false;
user: any = {
email: '',
password: ''
}
constructor(private http: httpService, private toast: ToastController) {
}
login() {
this.http.post('/api/v1/login/', this.user)
.subscribe(resp => {
//Your logic
}, err => {
//Your logic
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With