在发送HTTP请求之前执行条件方法

时间:2017-07-12 18:21:38

标签: angular http rxjs observable chain

Angular Chain Http Request

我创建了一个服务,其中包含了所有的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请求已经解决了!

我需要做什么?

  1. 方法返回Http请求
  2. 在发送请求之前获取令牌/设置令牌localStorage
  3. 继续Http请求,包括标题中的令牌
  4. 可能的解决方案 - 错误:
    @CozyAzure - 答案 enter image description here
    类型的参数'(session:any)=> void'不能分配给类型'的参数(值:any,index:number)=> ObservableInput< {}>”。   类型'void'不能分配给'ObservableInput< {}>'。

    尝试将 initClient(){...} 设置为“any”的类型
    initClient():任何{...} 上一个错误消失,但又出现了另一个错误:
    错误类型错误:您提供了“未定义”,其中包含预期的流。您可以提供Observable,Promise,Array或Iterable。

1 个答案:

答案 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)
    });