2017-08-02 25 views
6

Angular 2 üstünde oturan Ionic 2 kullanıyorumHTTP isteğimin yakalanmış bir hatadan sonra uygulamamda yayılmasına devam etmesine nasıl izin verebilirim?

Uygulamamda tüm API isteklerini işlemek için bir hizmet kullanıyorum. Bu taleplerden bazıları bir Yetkilendirme üstbilgisi taşır. API'sı, yetkisiz bir şekilde başarısız olursa 401'i döndürebilir ve şu anda kullanıcıya bir hata göstererek ve giriş ekranında gezinerek bunu ele alıyorum. Her şey harika çalışıyor ve mantığı işlemek için başka bir yere abone olduğum bu hatalar için bir olay yayınlıyorum (bir serviste gezinme denetleyicilerini kullanamıyorum). api.js hizmet için

Kodu: get istek gerçekleşiyor ise kullanıcıya göstermek

@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(); 
    } 
} 

sorun aşağı etmektir 'Yükleniyor ...' iletişim. Yöntem çağrılmadan önce bir yükleme iletişim kutusu oluşturup bunu başarı veya başarısızlığa uğratıyorum. Sorun şu ki, bir 401 veya 500 yakalandığında onu kapatmak için api.js'un içinde hiçbir kapsamım yok.

İşte bu çevrede benim mantık örneği verilmiştir:

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(); 
}); 

Bunun önemli olduğunu sanmıyorum, ama aynı zamanda da api.js hizmeti çağrıları her varlık için bir servis var. Yukarıdaki örnekte bu şuna benzer ki, this.trainingProgramme var:

get_programmes() { 
    let seq = this.api.get('training-programmes'); 

    seq 
     .subscribe(); 

    return seq; 
    } 

Ben ancak ben 'Yükleme' sorununu işleyebilir bir yol göremiyorum, bu tüm doğru yaklaştı şekilde düşündük.

Bir hata yakalandıktan sonra bile get yönteminin uygulamamda devam etmesinin bir yolu var mı, bu yüzden loader.dismiss() kodum doğru kapsamda mı çalışıyor?

Yükleyiciyi hizmetin içinde kullanmak zorunda kalmak istemiyorum (hatta eminim ki?) Bu kötü tasarım gibi görünüyor ve her zaman bir yükleyici göstermek istemiyorum. kontrolöre aittir.

cevap

1

İhtiyacınız olan şey, Gözlemlenebilir'de bir hata olsa bile her zaman çalışacak olan .finally işlecidür. Bir error olursa

complete geri arama (.subscribe çağrısından son) tetiklemez.

dahil etmeyi unutmayın: Bu arada

import 'rxjs/add/operator/finally'; 

... 

this.trainingProgramme.get_programmes() 
.finally(() => loader.dismiss()) 
.map(res => res.json()) 
.subscribe((res) => { 
    ... 
} 
, (err) => { 
    // Error 
    console.log(err); 
}); 

, yeni HttpClient için @angular/http verdiği kodu güncellemeyi düşünün.

+0

Hmm, bu çalışmıyor. Bir console.log() 'nihayet (() => console.log (' test ') 'içine ekledim ama hiçbir şey olmuyor - çıktı yok, 401 oluşumu ile hemen hemen aynı ve Yükleme ile görünen giriş ekranı ... dialog overlaid :( – Mike

+0

nihayet() yöntemini kullanarak burada çalışın.Bir hata ile uğraşmadan get_programmes() işlevinde bir kez gözlemlenebilir için abone oluyorsunuz. Bu hataya, hata işlemeden önce hata ve hata işleyicisi tetikleyebilir. Bu çizgiyi kaldırabilir ve herhangi bir fark olup olmadığını görebilir misiniz? – hagner

+0

Bu onu sıralar. Ekstra ara "subscribe()" erken tetiklemiş olmalı. Teşekkürler. – Mike

İlgili konular