2017-06-14 60 views
0

在我的API父類中,我實現了與服務器通信所需的所有方法。在Angular 2中重試連接到服務器回調失敗

@Injectable() 
export class ApiService { 
    constructor(protected http: Http, 
       protected snackBar: MdSnackBar) { 
    } 

    get<T>(resourceUrl: string, queryOptions?: { [key: string]: any; }): Observable<T> { 
    this.progressBarService.show(); 

    const endpoint = resourceUrl + this.createQueryString(queryOptions); 

    const callback =() => { return this.get<T>(resourceUrl, queryOptions); }; 

    return this.http.get(endpoint) 
     .map(this.extractData) 
     .catch((err: Response, caught: Observable<T>) => { 
     return this.catchError(err, this.snackBar, callback); 
     }) 
     .finally(() => { 
     this.progressBarService.hide(); 
     }); 
    } 

    protected catchError(error: Response | any, snackBar: MdSnackBar, callback: Function) { 
    if (!environment.production) { 
     console.error(error); 
    } 

    const errorMsg = 'Error while connecting the server.'; 

    const snackBarRef = snackBar.open(errorMsg, 'Retry', {duration: 3000}); 

    snackBarRef.onAction().subscribe(() => { 
     callback(); 
    }); 

    return Observable.throw(errorMsg); 
    } 
} 

如果錯誤發生了,我正在使用的catchError()函數來顯示一個snackBar使用靜態消息的用戶。如果用戶點擊「重試」按鈕,我使用回調函數重試連接。在catchError函數中使用callback()函數什麼也沒有發生。我確定callback被調用,因爲我甚至嘗試在其中放置一些console.log(),我可以在控制檯上看到消息。

+0

我認爲你的問題是第一次調用返回一個可能是(可能)訂閱的observable。第二個調用也返回一個可觀察對象,但可能沒有人正在訂閱它。 – Pace

+0

任何想法如何解決這個問題?也許增加一個'share()'? – Bagbyte

+0

對不起,太累了,今晚沒有提供完整的答案。想到的一個方法是創建一個主題。每次你打電話給get然後訂閱它(在'get '方法中)併發布到主題。然後返回主題。 – Pace

回答

1

喜歡的東西...

get<T>(resourceUrl: string, queryOptions?: { [key: string]: any; }, subject: Subject<T> = null): Observable<T> { 
    this.progressBarService.show(); 

    const endpoint = resourceUrl + this.createQueryString(queryOptions); 

    subject = subject || new Subject<T>(); 

    const callback =() => { return this.get<T>(resourceUrl, queryOptions, subject); }; 

    let obs = this.http.get(endpoint) 
     .map(this.extractData) 
     .catch((err: Response, caught: Observable<T>) => { 
     return this.catchError(err, this.snackBar, callback); 
     }); 

    obs.subscribe(res => { 
     this.progressBarService.hide(); 
     subject.next(res); 
     subject.complete(); 
    }); 

    return subject; 
    } 

我會改變的唯一的事情是,如果用戶以某種方式決定不重新發出請求,你應該叫subject.error()清理對象,並通知所有偵聽他們永遠不會得到答案。