2016-04-14 42 views
6

Hizmetimde, yetkili olmadığında kullanıcı yönlendiriliyorken bir davranışı tanımlamak istiyorum.Angular2: API bir hata döndürürse nasıl yönlendirilir?

export class MessagesService { 
    constructor (private http: Http) {} 

    private _usersUrl = '/users.json'; // URL to web api 


    getUsers() { 
     return this.http.get(this._usersUrl) 
      .map(res => <User[]> res.json().data) 
      .catch(this.handleError); 
    } 

    private handleError (error: Response) { 

     if (error.status == 401) { 
      // How do I tell Angular to navigate LoginComponent from here? 
     } else { 
      return Observable.throw(error.json().error || 'Server error'); 
     } 
    } 
} 

Sorularım şunlardır: hatta mümkünse

  • mi?
  • Bu iyi bir uygulama mı?
    • Evet, nasıl yaparım?
    • Hayır, başka nasıl yapabilirim? bizim takımda bu yaklaşan oldum
+0

Bkz http://stackoverflow.com/questions/36599523/angular-2-route-to-404-page-when-route-param-is-invalid/36609006#36609006 –

+0

@ GünterZöchbauer o kokan t Hizmete yönlendiriciyi kullanma hakkındaki sorumu yanıtla – Viktor

+0

Neden olmadığından emin değilsiniz. Eğer yönlendirici 'constructor (özel http: Http, özel yönlendirici: Router) {}' enjekte ederseniz onu kullanabilmeniz gerekir. Ayrıca sorunun altındaki bağlantıya bakınız. –

cevap

9

Benim yaklaşımım bunda bir göz atmak isterseniz 401 ve 403 vs.

aşağıya dahil ettiniz işlemek için gerçek istekle sarar bir önleme işlevi kendi isteği hizmeti oluşturmak ve sahip olmaktı .

import {Injectable} from "@angular/core" 
import {Subscription, Observable} from "rxjs" 
import {TokenModel} from "../../models/token.model" 
import {TokenService} from "../authentication/token.service" 
import {Http, Headers, URLSearchParams, RequestOptions, Request, RequestMethod} from "@angular/http" 
import {Router} from "@angular/router" 

@Injectable() 
export class RequestService 
{ 
    private baseUrl: string; 
    private subscription: Subscription; 
    private token: TokenModel; 

    constructor(public tokenService: TokenService, 
       public http: Http, 
       public router: Router) 
    { 
     this.baseUrl = `${process.env.API_URL}/example`; 
     this.subscription = this.tokenService.token$.subscribe(token => this.token = token); 
    } 

    get(path: string, params?: Object, withCredentials?: boolean): Observable<any> 
    { 
     this.checkAuthorised(); 

     const url: string = this.baseUrl + path; 
     const headers: Headers = new Headers({ 
      'Accept': 'application/json' 
     }); 

     const searchParams = new URLSearchParams(`user_session=${this.token.token}`); 

     for (let param in params) searchParams.set(param, params[param]); 

     const options: RequestOptions = new RequestOptions({ 
      url: url, 
      method: RequestMethod.Get, 
      headers: headers, 
      search: searchParams, 
      withCredentials: withCredentials 
     }); 

     const request = new Request(options); 

     return this.makeRequest(request); 
    } 

    post(path: string, body?: Object, params?: Object, useDataProperty?: boolean, withCredentials?: boolean): Observable<any> 
    { 
     this.checkAuthorised(); 

     const url: string = this.baseUrl + path; 

     const headers: Headers = new Headers({ 
      'Accept': 'application/json', 
      'Content-Type': 'application/json', 
     }); 

     const data = JSON.stringify(useDataProperty ? {data: body} : body); 

     const searchParams = new URLSearchParams(`user_session=${this.token.token}`); 

     for (let param in params) searchParams.set(param, params[param]); 

     const options: RequestOptions = new RequestOptions({ 
      url: url, 
      method: RequestMethod.Post, 
      headers: headers, 
      body: data, 
      search: searchParams, 
      withCredentials: withCredentials 
     }); 

     const request = new Request(options); 

     return this.makeRequest(request); 
    } 

    makeRequest(request: Request) 
    { 
     return this.intercept(this.http.request(request).map(res => res.json())); 
    } 

    intercept(observable: Observable<any>) 
    { 
     return observable.catch(err => 
     { 

      if (err.status === 401) 
      { 
       return this.unauthorised(); 

      } else if (err.status === 403) 
      { 
       return this.forbidden(); 
      } else 
      { 
       return Observable.throw(err); 
      } 
     }); 
    } 

    unauthorised(): Observable<any> 
    { 
     this.tokenService.clear(); 
     this.router.navigate(['/login']); 
     return Observable.empty(); 
    } 

    forbidden(): Observable<any> 
    { 
     this.router.navigate(['/']); 
     return Observable.empty(); 
    } 

    checkAuthorised(): void 
    { 
     if (!this.token.token.length) 
     { 
      this.router.navigate(['login']); 
     } 
    } 


} 
+0

Bir bağlantıyı göndermenin iyi bir fikir olduğunu düşünmüyorum. Genciniz bir gün kaldırılabilir. Kodunuzu buraya göndermenin daha iyi olduğunu düşünüyorum. – Viktor

0

Bir yönü bir API istemcisi sınıf uygulama gereğidir. Bu API istemcisi, orijinal Http hizmetini sarar.

fikri Http hizmet gözlenebilirlerini üretir beri kolayca Http hizmeti tarafından üretilen orijinal gözlemlenebilir için map, flatMap ve catch operatörleri gibi ekleyerek operatörler tarafından davranışını uzatabilirsiniz olmasıdır.

Bu örneğe sahip olduğunuz sorunu gidermek için yararlı bir başlangıç ​​noktası bulacağınızı düşünüyorum.

import { ApiRequestOptions } from './api-request-options.service'; 
import { Http, Response, RequestOptions, ResponseContentType } from '@angular/http'; 

import 'rxjs/add/observable/zip'; 
import 'rxjs/add/operator/map'; 
import { Observable } from 'rxjs/Rx'; 
import { Injectable } from '@angular/core'; 
import { Router } from '@angular/router'; 

@Injectable() 
export class ApiClient { 
    // PLease note, the API request options service is a helper that we introduced 
    // to generate absolute URLs based on settings in the client. 
    // I did not include it here for brevity. 
    constructor(private router: Router, private http: Http, private requestOptions: ApiRequestOptions) { 

    } 

    get<TResponse>(path: string, queryStringParams?: any): Observable<TResponse> { 
     let self = this; 

     return Observable.zip(
      this.requestOptions.absoluteUrlFor(path, queryStringParams), 
      this.requestOptions.authorizedRequestOptions() 
     ).flatMap(requestOpts => { 
      let [url, options] = requestOpts; 
      return self.http.get(url, options); 
     }).catch(response => { 
      if (response.status === 401) { 
       self.router.navigate(['/login']); 
      } 

      return response; 
     }).map((response: Response) => <TResponse>response.json()); 
    } 

    post<TResponse>(path: string, body: any): Observable<TResponse> { 
     let self = this; 

     return Observable.zip(
      this.requestOptions.absoluteUrlFor(path), 
      this.requestOptions.authorizedRequestOptions() 
     ).flatMap(requestOpts => { 
      let [url, options] = requestOpts; 
      return self.http.post(url, body, options); 
     }).catch(response => { 
      if (response.status === 401) { 
       self.router.navigate(['/login']); 
      } 

      return response; 
     }).map((response: Response) => <TResponse>response.json()); 
    } 

    put<TResponse>(path: string, body: any): Observable<TResponse> { 
     let self = this; 

     return Observable.zip(
      this.requestOptions.absoluteUrlFor(path), 
      this.requestOptions.authorizedRequestOptions() 
     ).flatMap(requestOpts => { 
      let [url, options] = requestOpts; 
      return self.http.put(url, body, options); 
     }).catch(response => { 
      if (response.status === 401) { 
       self.router.navigate(['/login']); 
      } 

      return response; 
     }).map((response: Response) => { 
      if (response.status === 200) { 
       return <TResponse>response.json(); 
      } else { 
       return null; 
      } 
     }); 
    } 

    delete(path: string): Observable<Response> { 
     let self = this; 

     return Observable.zip(
      this.requestOptions.absoluteUrlFor(path), 
      this.requestOptions.authorizedRequestOptions() 
     ).flatMap(requestOpts => { 
      let [url, options] = requestOpts; 
      return self.http.delete(url, options); 
     }).catch(response => { 
      if (response.status === 401) { 
       self.router.navigate(['/login']); 
      } 

      return response; 
     }); 
    } 
} 
İlgili konular