2017-08-02 14 views
6

मैं आयोनिक 2 का उपयोग कर रहा हूं जो कोणीय 2 के शीर्ष पर बैठता है।कैप्चर विफलता के बाद मैं अपने HTTP अनुरोध को अपने ऐप के माध्यम से प्रचार करने की अनुमति कैसे दे सकता हूं?

मैं सभी एपीआई अनुरोधों को संभालने के लिए अपने ऐप में एक सेवा का उपयोग कर रहा हूं। उनमें से कुछ अनुरोध प्राधिकरण शीर्षलेख लेते हैं। अगर एथ्यू विफल रहता है तो मेरा एपीआई 401 लौटा सकता है, और मैं वर्तमान में उपयोगकर्ता को एक त्रुटि दिखाकर और लॉगिन स्क्रीन पर नेविगेट करके इसे संभालने में सक्षम हूं। यह सब बहुत अच्छा काम करता है और मैं इन त्रुटियों के लिए एक ईवेंट प्रकाशित करता हूं जिसे मैं तर्क को संभालने के लिए कहीं और सदस्यता लेता हूं (क्योंकि मैं सेवा में नेविगेशन नियंत्रकों का उपयोग नहीं कर सकता)।

api.js सेवा के लिए कोड:

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

समस्या के लिए नीचे है 'लोड हो रहा है ...' संवाद है कि मैं उपयोगकर्ता को दिखाए जबकि get अनुरोध हो रहा है। विधि कहने से पहले मैं एक लोडिंग संवाद बना देता हूं और इसे सफलता या विफलता पर खारिज कर देता हूं। समस्या यह है कि 401 या 500 पकड़े जाने पर इसे खारिज करने के लिए api.js के अंदर मेरे पास इसका कोई दायरा नहीं है।

यहाँ इस के आसपास मेरे तर्क का एक नमूना है:

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

मुझे नहीं लगता कि यह महत्वपूर्ण है, लेकिन मैं यह भी प्रत्येक इकाई है जो बदले में api.js सेवा कॉल के लिए एक सेवा है। ऊपर के उदाहरण में यह जो इस तरह दिखता है, this.trainingProgramme है:

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

    seq 
     .subscribe(); 

    return seq; 
    } 

मैं जिस तरह से मैं संपर्क किया यह सब सही था सोचा, लेकिन मैं एक तरह से मैं 'लोड हो रहा है' इस मुद्दे को संभाल कर सकते हैं नहीं देख सकता।

क्या कोई तरीका है कि मेरे पास get विधि मेरे ऐप के भीतर एक त्रुटि पकड़े जाने के बाद भी जारी हो सकती है, ताकि मेरा loader.dismiss() कोड सही दायरे में चलाया जा सके?

मैं वास्तव में सेवा के अंदर लोडर का उपयोग नहीं करना चाहता (यकीन नहीं कि मैं भी सक्षम हूं?) क्योंकि यह खराब डिज़ाइन जैसा लगता है, और मैं हमेशा लोडर नहीं दिखाना चाहता, इसलिए यह नियंत्रक में आता है।

उत्तर

1

आपको क्या चाहिए .finally ऑपरेटर, जो पर्यवेक्षण पर कोई त्रुटि होने पर भी निष्पादित करेगा।

complete कॉलबैक (.subscribe कॉल से अंतिम) error होता है तो ट्रिगर नहीं होगा।

यह शामिल करना न भूलें:

import 'rxjs/add/operator/finally'; 

... 

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

वैसे, नई HttpClient को @angular/http से अपना कोड अपडेट करने पर विचार करें।

+0

हम्म, यह काम नहीं कर रहा है। मैंने एक कंसोल.लॉग() को 'अंत में (() => console.log (' test ') में जोड़ा लेकिन कुछ भी नहीं होता - कोई आउटपुट नहीं, जैसा कि 401 के साथ पहले और लोडिंग स्क्रीन के साथ दिखाई देने वाली स्क्रीन स्क्रीन ... संवाद ओवरलैड :( – Mike

+0

अंत में() विधि का उपयोग करना यहां काम करना चाहिए। आप किसी भी त्रुटि को संभाले बिना get_programmes() फ़ंक्शन में एक बार देखने योग्य की सदस्यता ले रहे हैं। शायद यह सबसिबर त्रुटि को संभालने से पहले त्रुटि और त्रुटि हैंडलर को ट्रिगर करता है क्या आप उस लाइन को हटा सकते हैं और देख सकते हैं कि कोई अंतर है या नहीं? – hagner

+0

इसे हल किया गया है। अतिरिक्त इंटरमीडिएट 'सब्सक्राइब()' इसे शुरुआती रूप से ट्रिगर कर रहा होगा। धन्यवाद। – Mike

संबंधित मुद्दे

 संबंधित मुद्दे