How to handle an empty result with rxjs observable

╄→гoц情女王★ 提交于 2019-12-25 01:02:34

问题


I have an API that might return [] result.

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:...

[]

Here is my code that just does not work in that particular case:

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); executing the http call and returns type of 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')
    });
  }

I have no errors on console.

What is the best practice to handle that scenario?

UPDATE:

I did change the api so now it is returns the data this way:

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'
}

This way I always have the data in responce and my code works with a small modifications (aData.data and bData.data) however I still wonder why it didnt wrok in case of empty array, as @DanielWStrimpel commented it should emmit a value anyway...?


回答1:


First, there is a problem with your post method (perceive empty array as no response body) or your API (return empty response body instead of empty array), either ways, now when you get empty data, it will just complete the request and return nothing.

Second, there is a workaround for this problem (while I prefer to add the status field to the response body like you did), is to use RxJS toArray, like this:

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

Note: As you can see, toArray emits an array of all items that the Observable emitted, that mean that in your case, if will return either an empty array or an array contains your data array [[item1, item2]].



来源:https://stackoverflow.com/questions/49868347/how-to-handle-an-empty-result-with-rxjs-observable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!