Używam Ionic 2, który znajduje się na górze Angular 2.W jaki sposób mogę zezwolić na kontynuowanie propagacji mojego żądania HTTP za pośrednictwem mojej aplikacji po przechwyceniu błędu?
Używam usługi w mojej aplikacji do obsługi wszystkich żądań API. Niektóre z tych żądań mają nagłówek Authorization. Mój interfejs API może zwrócić kod 401, jeśli autoryzacja nie powiedzie się, a ja aktualnie zajmuję się tym, pokazując błąd użytkownikowi i kierując go do ekranu logowania. To wszystko działa świetnie i publikuję wydarzenie dla tych błędów, które subskrybuję gdzie indziej, aby obsłużyć logikę (ponieważ nie mogę używać kontrolerów nawigacyjnych w usłudze).
Kod api.js
usługi:
@Injectable()
export class Api {
base_url: string = 'https://***.com';
url: string = this.base_url + '/api/v1';
authurl: string = this.base_url + '/oauth/token';
grant_type: string = 'password';
client_id: string = '1';
client_secret: string = '***';
access_token: string;
constructor(
public http: Http,
private storage: Storage,
public events: Events) {
// Grab access token and store it
storage.get('access_token').then((val) => {
this.access_token = val;
});
}
// Performs a GET request with auth headers
get(endpoint: string, params?: any) {
if(!params) {
params = [];
}
params['grant_type'] = this.grant_type;
params['client_id'] = this.client_id;
params['client_secret'] = this.client_secret;
let headers: Headers = this.getHeaders();
return this.getApiToken().flatMap(data => {
headers.append('Authorization', 'Bearer ' + data);
let options = new RequestOptions({ headers: headers });
// Support easy query params for GET requests
if (params) {
let p = new URLSearchParams();
for (let k in params) {
p.set(k, params[k]);
}
// Set the search field if we have params and don't already have
// a search field set in options.
options.search = !options.search && p || options.search;
}
return this.http.get(this.url + '/' + endpoint, options)
.catch((error: any) => {
if (error.status === 500) {
this.events.publish('api:generalError', error);
return Observable.throw(new Error(error.status));
}
else if (error.status === 401) {
this.events.publish('api:unauthorized', error);
return Observable.throw(new Error(error.status));
}
});
}).share();
}
}
Problem jest w dół do „Ładowanie ...” dialogowe, które mogę pokazać użytkownikowi, gdy żądanie get
ma miejsce. Zanim zostanie wywołana metoda, utworzę okno dialogowe ładowania i odrzucę je w przypadku sukcesu lub niepowodzenia. Problem polega na tym, że nie mam żadnego zakresu tego wewnątrz api.js
, aby go odrzucić, gdy złapie 401 lub 500.
Oto próbka mojego logiki wokół to:
let loader = this.loadingCtrl.create({
content: "Please wait..."
});
loader.present();
this.trainingProgramme.get_programmes()
.map(res => res.json())
.subscribe((res) => {
this.currentItems = res.training_programmes;
}, (err) => {
// Error
console.log(err);
},() => {
loader.dismiss();
});
Nie sądzę, że to ważne, ale mam również usługi dla każdego podmiotu, który z kolei wywołuje api.js
usługi. W powyższym przykładzie jest to this.trainingProgramme
, który wygląda tak:
get_programmes() {
let seq = this.api.get('training-programmes');
seq
.subscribe();
return seq;
}
myślałem tak, jak zbliżył się to wszystko było poprawne, jednak nie widzę sposób mogę poradzić z „załadunku” problem.
Czy istnieje sposób mogę mieć metodę get
dalszym ciągu mojej aplikacji nawet po błąd został złapany, tak, że mój kod loader.dismiss()
jest prowadzony w prawidłowym zakresie?
Naprawdę nie chcę używać ładowarki wewnątrz usługi (nie jestem pewien, czy jestem w stanie to zrobić?), Ponieważ wygląda na to, że jest to zły projekt, i nie chcę zawsze wyświetlać programu ładującego, więc należy do kontrolera.
Hmm, to nie działa. Dodałem konsolę console.log() do 'finally (() => console.log ('testing')', ale nic się nie dzieje - brak danych wyjściowych, tak samo jak poprzednio z pojawieniem się 401 i ekranem logowania pojawiającym się przy ładowaniu ... okno dialogowe nałożone :( – Mike
Powinna działać tutaj metoda finally() Subskrybujesz to, co można zaobserwować w funkcji get_programmes(), nie powodując żadnych błędów. Być może ten subskrybent uruchamia obsługę błędów i błędów, zanim zajmie się błędem Czy mógłbyś usunąć tę linię i zobaczyć, czy jest jakaś różnica? – hagner
To jest posortowane, dodatkowe pośrednie 'subscribe()' musiało wywołać to wcześniej. – Mike