Я пытаюсь написать Угловую службу, которая будет обертывать обычную службу Http и автоматически совершать вызовы аутентификации, если токен-носитель недоступен или недействителен.ReactiveX наблюдаемый, который использует другой наблюдаемый
Вот пример регулярного GET вызова, сделанный с помощью сервиса:
this.httpWithAutomagicAuth
.get("http://localhost:5001/books")
.map(res => res.json())
.subscribe(
data => {
self.data = data;
}
);
А вот моя очень неаккуратно реализации такого сервиса. Очевидно, что я не использую правильные идиомы ReactiveX в коде.
Как вы можете легко заметить, я пытаюсь построить наблюдаемое (Observable.create), которое использует другое наблюдаемое, возвращаемое this.login(). Я уверен, что существует лучший способ привязки/вложения, наблюдаемый для этого сценария.
Пожалуйста, предлагает усовершенствование, которые сделают код:
- лаконична
легко читать и понимать
@Injectable() export class HttpWebApiAuthService { constructor(private http: Http) { } // ... public get(url: string, options?: RequestOptionsArgs): Observable<Response> { // TODO this code is for test purpose only (basically, it required to enforce the jwtToken retrieval branch execution) // this.clearJwtToken(); if (!this.getJwtToken()) { return Observable.create( (result: Observer<Response>) => { this.login() .map(res => res.json()) .subscribe( data => { this.saveJwtToken(data.id_token); this.executeGet(url, options) .subscribe(authenticationResult => { result.next(authenticationResult); }); }, error => { console.error("Authentication error", error); }, () => { console.info("Authentication complete"); } ); }, error => { console.error("OBSERVABLE error: ", error); }, () => { console.info("OBSERVABLE complete"); } ); } else { return this.executeGet(url, options); } } private login() : Observable<Response> { const authBody = { "client_id": "...", "username": "...", "password": "...", // ... }; const headers = new Headers(); headers.append("Content-Type", "application/json"); return this.http.post("https://AUTH_URL", JSON.stringify(authBody), { headers: headers }); } // ... }