2016-04-14 20 views
6

Trong dịch vụ của tôi, tôi muốn mô tả hành vi khi người dùng đang được chuyển hướng nếu không được ủy quyền.Angular2: cách chuyển hướng nếu API trả về lỗi?

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

Câu hỏi của tôi là:

  • Là nó thậm chí có thể?
  • Đó có phải là thực tiễn tốt không?
    • Nếu có, tôi làm cách nào để thực hiện điều đó?
    • Nếu không, tôi có thể làm như thế nào khác?
+0

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

+0

@ GünterZöchbauer nó doesn' t trả lời câu hỏi của tôi về việc sử dụng bộ định tuyến trong dịch vụ – Viktor

+0

Không chắc chắn lý do. Nếu bạn tiêm bộ tạo 'router (private http: Http, private router: Router) {}' bạn sẽ có thể sử dụng nó. Xem thêm liên kết bên dưới câu hỏi. –

Trả lời

9

Tiếp cận của tôi là tạo ra dịch vụ theo yêu cầu riêng của tôi và có một chức năng đánh chặn mà kết thúc tốt đẹp theo yêu cầu thực tế để xử lý 401 và 403, vv

đã bao gồm nó dưới đây nếu bạn muốn có một cái nhìn vào nó .

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

Tôi không nghĩ rằng việc đăng liên kết là một ý tưởng hay. Gist của bạn có thể được gỡ bỏ một ngày. Tôi nghĩ tốt hơn nên đăng mã của bạn ở đây. – Viktor

0

Một hướng chúng tôi đã tiếp cận này nhóm của chúng tôi là bằng cách thực hiện một lớp khách hàng API. Ứng dụng API này kết thúc tốt đẹp dịch vụ Http gốc.

Ý tưởng là kể từ khi dịch vụ Http sản xuất quan sát bạn có thể dễ dàng mở rộng hành vi của nó bằng cách khai thác thêm như map, flatMapcatch khai thác các quan sát ban đầu được tạo ra bởi các dịch vụ Http.

Tôi nghĩ bạn sẽ thấy ví dụ này là điểm khởi đầu hữu ích để khắc phục sự cố bạn đang gặp phải.

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; 
     }); 
    } 
} 
Các vấn đề liên quan