存储服务api调用的响应

时间:2017-05-22 12:28:56

标签: javascript angular angular2-services

我尝试使用以下代码将http服务包装在角度2中:

@Injectable()
export class HttpSuperService {
    private baseUrl: string;
    constructor(private http: Http) {
    }

    get(url: string): Observable<string> {
        return (
            this.baseUrl ? 
            Observable.of(this.baseUrl) :
            this.http.get('/config/').map((res: Response) => res)
        )
        .flatMap((res: any) => {
            this.baseUrl = res._body;
            return this.http.get(this.baseUrl + url)
                .map((res2: Response) => res2.json());
        });
    }
}

我尝试做的是第一次请求获取应用程序的baseUrl(API在另一个URL上),但只发出一次请求(第一次)。

它适用于第一个请求,但第二个请求(当另一个组件使用相同的服务时,IE)不起作用,因为&#34; Observable.of&#34;出现了问题。我知道我需要以某种方式使用Response而不是字符串......这让我开始考虑这种方法。有更好的方法吗?

这个解决方案有效但感觉有点冗长,因为我打算在此服务中添加其他方法(POST,PUT):

@Injectable()
export class HttpSuperService {
private baseUrl: string;
constructor(private http: Http) {
}

get(url: string): Observable<string> {
    if (this.baseUrl) {
        return this.http.get(this.baseUrl + url).map((res2: Response) => res2.json());
    }
    return this.http.get('/config/').map((res: Response) => res)
        .flatMap((res: any) => {
            this.baseUrl = res._body;
            return this.http.get(this.baseUrl + url).map((res2: Response) => res2.json());
        });
    }
}

2 个答案:

答案 0 :(得分:0)

您可以将对API网址检索的依赖性分解为专用方法。该方法还可以处理一些中间步骤,例如url连接,以进一步减少重复。

例如:

import {Http} from '@angular/http';
import {Inject} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mapTo';
import 'rxjs/add/operator/do';

let baseUrl: string;

@Inject export class HttpSuperService {
  routeUrl(url: string) {
    return baseUrl
      ? Observable.of(baseUrl + url)
      : this.http.get('/config/')
        .do(response => baseUrl = response.text())
        .mapTo(baseUrl + url);
  }

  constructor(readonly http: Http) {}

  get(url: string): Observable<string> {
    return this.routeUrl(url)
      .flatMap(this.http.get)
      .map(res => res.json());
  }

  post(url: string, body: Something): Observable<Something> {
    return this.routeUrl(url)
      .flatMap(url => this.http.post(url, body))
      .map(response => <Something>response.json());
  }
}

我认为这是合理的,但我们可以做得更好,我们可以更干(没有太干的事情)):

@Inject export class HttpSuperService {
  constructor(readonly http: Http) {}

  routeUrl(url: string) {
    return baseUrl
      ? Observable.of(baseUrl + url)
      : this.http.get('/config/')
        .do(response => baseUrl = response.text())
        .mapTo(baseUrl + url);
  }

  request<R>(url: string, makeRequest: (url: string, body?: {}) => Observable<Response>) {
    return this.routeUrl(url)
      .flatMap(url => makeRequest(url))
      .map(response => <R>response.json());
  }

  get(url: string): Observable<string> {
    return this.request<string>(url, fullUrl => this.http.get(fullUrl));
  }

  post(url: string, body: Something): Observable<Something> {
    return this.request<Something>(url, fullUrl => this.http.post(fullUrl, body));
  }
}

我对URL处理并不完全满意,我可能会进一步重构它,但我们已经大大减少了重复。

答案 1 :(得分:-1)

我总是使用这种方法,对我来说很好,我希望它有用:

在我的服务文件中:

getSomething(){
    return this._http.get('YOUR-API-ENDPOINT').map(res=> res.json());
}

在我的组件中我使用它来订阅Observable

return this._myServiceName.getSomething().subscribe(data =>{
  this.muyData=data;
}