Javascript 存储来自服务api调用的响应

Javascript 存储来自服务api调用的响应,javascript,angular,angular2-services,Javascript,Angular,Angular2 Services,我尝试使用以下代码将http服务包装到angular 2中: @Injectable() export class HttpSuperService { private baseUrl: string; constructor(private http: Http) { } get(url: string): Observable<string> { return ( this.baseUrl ?

我尝试使用以下代码将http服务包装到angular 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());
        });
    }
}
@Injectable()
导出类HttpSuperService{
私有baseUrl:string;
构造函数(专用http:http){
}
get(url:string):可观察{
返回(
这个.baseUrl?
可观察的(this.baseUrl):
this.http.get('/config/').map((res:Response)=>res)
)
.flatMap((res:any)=>{
this.baseUrl=res.\u body;
返回this.http.get(this.baseUrl+url)
.map((res2:Response)=>res2.json());
});
}
}
我试图做的是发出第一个请求来获取应用程序的baseUrl(API位于另一个URL上),但只发出一次请求(第一次)

它在第一个请求上工作,但第二个请求(即当另一个组件使用相同的服务时)不工作,因为“Observable.of”有问题。我知道我需要以某种方式使用响应,而不是字符串……这让我开始考虑这种方法。有更好的方法吗

此解决方案可行,但感觉有点冗长,因为我还计划向此服务添加其他方法(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());
        });
    }
}
@Injectable()
导出类HttpSuperService{
私有baseUrl:string;
构造函数(专用http:http){
}
get(url:string):可观察{
if(this.baseUrl){
返回this.http.get(this.baseUrl+url).map((res2:Response)=>res2.json());
}
返回此.http.get('/config/').map((res:Response)=>res)
.flatMap((res:any)=>{
this.baseUrl=res.\u body;
返回this.http.get(this.baseUrl+url).map((res2:Response)=>res2.json());
});
}
}

我一直使用这种方法,对我来说效果很好,我希望它有用:

在我的服务文件中:

getSomething(){
    return this._http.get('YOUR-API-ENDPOINT').map(res=> res.json());
}
在我的组件中,我使用它来订阅可观察的

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

您可以将对API url检索的依赖性分解为专用方法。该方法还可以处理一些中间步骤,如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());
  }
}
从'@angular/Http'导入{Http};
从“@angular/core”导入{Inject};
从“rxjs/Observable”导入{Observable};
导入'rxjs/add/operator/mergeMap';
导入“rxjs/add/observable/fromPromise”;
导入'rxjs/add/operator/map';
导入'rxjs/add/operator/mapTo';
导入'rxjs/add/operator/do';
让baseUrl:string;
@注入导出类HttpSuperService{
routeUrl(url:string){
返回baseUrl
可观察的(基本url+url)
:this.http.get(“/config/”)
.do(response=>baseUrl=response.text())
.mapTo(baseUrl+url);
}
构造函数(只读http:http){}
get(url:string):可观察{
返回此.routeUrl(url)
.flatMap(this.http.get)
.map(res=>res.json());
}
post(url:string,body:Something):可观察{
返回此.routeUrl(url)
.flatMap(url=>this.http.post(url,body))
.map(response=>response.json());
}
}
我认为这是合理的,但我们可以做得更好,我们可以更干燥(没有太干燥的事情:):

@注入导出类HttpSuperService{
构造函数(只读http:http){}
routeUrl(url:string){
返回baseUrl
可观察的(基本url+url)
:this.http.get(“/config/”)
.do(response=>baseUrl=response.text())
.mapTo(baseUrl+url);
}
请求(url:string,makeRequest:(url:string,body?:{})=>可观察){
返回此.routeUrl(url)
.flatMap(url=>makeRequest(url))
.map(response=>response.json());
}
get(url:string):可观察{
返回this.request(url,fullUrl=>this.http.get(fullUrl));
}
post(url:string,body:Something):可观察{
返回this.request(url,fullUrl=>this.http.post(fullUrl,body));
}
}

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

是的,这会起作用,但这不是我真正想要做的。嗨!谢谢你的评论,我删除了我的答案,以避免给别人提供不好的信息。但是,如果您可以或有时间的话,您能更好地向我解释一下“不要将未绑定实例方法传递给回调”是什么意思吗?@SrAxi如果有人更改回调,使其使用
,程序将在没有警告的情况下中断。因此,如果将方法作为参数传递,则必须首先绑定它
setTimeout(this.method.bind(this))
,但要使用箭头函数
setTimeout(()=>this.method())。签出这个答案非常感谢!我会看一看并检查我的代码。;)
@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));
  }
}