I'm working with HttpClientModule from angular 4.3 on Ionic 3. My application communicates with a Django server that asks for an authentication header that is being sent by an interceptor. The problem I'm facing is that when I ask HttpClientModule to perform the get request, it sends two requests. One with the authentication header, that is not responded, and other with no authentication header. Can anyone help me? I don't know what I am doing wrong :(
Here's what I see in the Web Inspector:
Here's my Provider:
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { LoadingController, AlertController } from 'ionic-angular';
@Injectable()
export class RestProvider {
private url = "http://10.0.1.50:8000/";
constructor(public http: HttpClient, private alertCtrl: AlertController, private loadingCtrl: LoadingController) { }
getDisp(){
return new Promise(resolve => {
this.http.get(this.url+'api/Dispositivos').subscribe(data => {
console.log(data);
resolve(data);
}, (err: HttpErrorResponse) => {
if (err instanceof ErrorEvent){
let alert = this.alertCtrl.create({
title: 'Algo deu errado :(',
subTitle: 'Parece que há algo errado com a sua conexão. Tente novamente',
buttons: ['OK']
});
alert.present();
} else {
let alert = this.alertCtrl.create({
title: 'Algo deu errado :(',
subTitle: 'Desculpe, parece que nossos servidores estão com problemas. Tente novamente em alguns minutos',
buttons: ['OK']
});
alert.present();
}
});
});
}
}
And here's my interceptor:
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
public credenciais: any;
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (localStorage.credenciais != null) {
this.credenciais = JSON.parse(localStorage.credenciais)
request = request.clone({
setHeaders: {
Authorization: 'Token '+this.credenciais.token
}
});
}
return next.handle(request);
}
}
Here's the function I use to call the Provider:
import { NavController } from 'ionic-angular';
import { LoginPage } from "../../pages/login/login";
import { RestProvider } from '../../providers/rest/rest';
[...]
constructor(public navCtrl: NavController, public restProvider: RestProvider) {}
[...]
carregaDisp(){
return new Promise(resolve => {
this.restProvider.getDisp().then(data => {
if (data == null) {
this.navCtrl.setRoot(LoginPage);
} else {
this.dispositivo = data;
this.atualizaStatus().then(() => {
console.log(data);
resolve();
});
}
});
});
}
I don't know what I am doing wrong and I've Googled everything I could think of. Sorry if it's a beginners mistake, but I can't find it's solution :(
I see problem with your RestProvider. You shouldn't subscribe to the observable like that. You only subscribe to observable when you want to actually get the response, I mean at the place of usage and not inside wrapper methods. It will cause memory leaks. You should unsubscribe from the observables as well and your way doesn't allow you to do so.
Please use something like this. This way you will get the advantage of new pipeable operators and get clean declarative code.
import { of } from 'rxjs';
import { catchError } from 'rxjs/operators';
getDisp(): Promise<any> {
return this.http
.get(this.url + 'api/Dispositivos')
.pipe(
catchError(err => {
this.processError(err);
return of(err);
}),
)
.toPromise();
}
processError(err) {
if (err instanceof ErrorEvent) {
let alert = this.alertCtrl.create({
title: 'Algo deu errado :(',
subTitle:
'Parece que há algo errado com a sua conexão. Tente novamente',
buttons: ['OK'],
});
alert.present();
} else {
let alert = this.alertCtrl.create({
title: 'Algo deu errado :(',
subTitle:
'Desculpe, parece que nossos servidores estão com problemas. Tente novamente em alguns minutos',
buttons: ['OK'],
});
alert.present();
}
}
Example use case of this method will be:
async refresh() {
const response = await this.getDisp();
console.log('response of the getdisp is : ', response);
}