如何使用rxjs observable处理空结果

时间:2018-04-17 01:10:17

标签: angular rxjs observable

我有一个可能会返回[]结果的API。

HTTP/1.1 200 OK
Date: Tue, 16 Apr 2018 06:06:22 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
Request-Context: appId=cid-v1:...

[]

这是我的代码,在这种情况下不起作用:

getData(): Observable<Thing[]> {
    return this.getData1()
    .pipe(
      flatMap(aData => {
        const ids = aData.map(({ id }) => id);
        const bData = this.getBData(ids); // emty result might be here

        //test subscribe
        this.getBData(ids).subscribe((data) => {
          //just had that for a test, to confirm subsscribe never fires when response is `[]`
          console.log(data);
        });

        return Observable.zip(
          Observable.of(aData),
          bData
        );
      }),
      // map does not executing when api that getting called by `this.getBData(ids)` returns `[]`
      map(([aData, bData]) => {
        // Merge the results
        const data: any = aData.concat(bData).reduce((acc, x) => {
          acc[x.scriptNumber] = Object.assign(acc[x.scriptNumber] || {}, x);
          return acc;
        }, {});
        return Object.values(data);
      })
    );
  }

this.getBData(ids);执行http调用并返回类型Observable<Thing[]>

  getBData(ids):Observable<Thing[]> {
    const filters = {
      'id': [ids],
    };
    return this.http.post<Thing[]>('http://localhost:8080/api/thing', JSON.stringify(filters), {
      headers: new HttpHeaders().set('Content-Type', 'application/json')
    });
  }

我在控制台上没有错误。

处理该方案的最佳做法是什么?

更新

我确实更改了api所以现在它以这种方式返回数据:

HTTP/1.1 200 OK
Date: Tue, 17 Apr 2018 09:36:11 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
Request-Context: appId=cid-v1:...

{
  data: [],
  error: 'OK'
}

这样我总是在响应中有数据,而我的代码只需要很少的修改(aData.databData.data)但是我仍然想知道为什么它在空数组的情况下没有像@DanielWStrimpel一样评论说它应该发出一个价值......?

1 个答案:

答案 0 :(得分:0)

首先,你的post方法(感知空数组没有响应体)或你的API(返回空响应体而不是空数组)存在问题,无论哪种方式,现在当你得到空数据时,它只会完成请求并且不返回任何内容。

其次,这个问题有一个解决方法(虽然我更喜欢像你一样将status字段添加到响应主体),但是要使用RxJS toArray,如下所示:

this.getBData(ids)
    .pipe(toArray())
    .subscribe(([bData]) => {
      // Process the data
    });

注意:正如您所看到的,toArray会发出Observable发出的所有项的数组,这意味着在您的情况下,if将返回一个空数组或数组包含您的数据数组{{1 }}