我创建了一个服务,其中包含了所有的HTTP请求(get,put,post ......)。
get(url) {
const headers = new Headers();
this.sessionToken(headers); // just add the headers...
return this.http.get(url, {
headers: headers
});
}
如何在发送(例如)GET请求之前执行方法?
在我的场景中,我有一个方法可以返回一个令牌,这个令牌需要保存在localStorage上,并在链接后附加到标题!
initClient() {
return this.http.post('/connect/', {})
.map(res => res.json())
}
如何在Http调用完成之前有条件地插入此请求?
直接在此服务中,不会订阅每个HTTP调用。
这是我试图做的事情:
get(url) {
if (!localStorage.getItem('token')) {
this.initClient()
.subscribe(session => {
localStorage.setItem('token', JSON.stringify(session));
});
}
const headers = new Headers();
this.sessionToken(headers);
return this.http.get(url, {
headers: headers
});
}
但是在调用initClient()之前,HTTP请求已经解决了!
我需要做什么?
可能的解决方案 - 错误:
@CozyAzure - 答案
类型的参数'(session:any)=> void'不能分配给类型'的参数(值:any,index:number)=> ObservableInput< {}>”。
类型'void'不能分配给'ObservableInput< {}>'。
尝试将 initClient(){...} 设置为“any”的类型:
initClient():任何{...} 上一个错误消失,但又出现了另一个错误:
错误类型错误:您提供了“未定义”,其中包含预期的流。您可以提供Observable,Promise,Array或Iterable。
答案 0 :(得分:1)
您需要的是Observable.flatMap()
。 flatMap()
就像承诺中的.then()
一样。
此外,根据您的问题,您可以从Observable.if()
获得一些帮助,使您的代码看起来更干净。 Observable.if(condition, thenSource, [elseSource])
接受3个参数。第一个参数是布尔条件,第二个参数是条件为真时要发出的Observable,最后一个是else源数组,如果条件为假则将被释放。
这样的事情:
get(url) {
return Observable
.if(
//a function that returns a boolean
() => !localStorage.getItem('token'),
//an Observable to return if condition is true
this.initClient()
//use flatMap to proceed to next Observable
.flatMap(session => {
return localStorage.setItem('token', JSON.stringify(session));
}),
//an Observable to return if condition is false
//return dummy value so that Observable can continue
Observable.of('')
)
.flatMap(() => {
const headers = new Headers();
this.sessionToken(headers);
return this.http.get(url, {
headers: headers
});
})
}
现在您可以在组件中调用get(url)
:
this.myService.get(API_URL)
.subscribe(response => {
console.log(response)
});