简体   繁体   中英

How to handle an API response that might be an empty object with rxjs Observables?

I can edit both the frontend and the backend

I have a service that fetches a communique. This communique might exist (there is one communique active) or might not (there is no communique active), so the API might respond with the JSON object of the communique, or with an empty JSON object.

I am handling it this way:

getCommunique(): Observable<Communique | {}> {
  return this.http.get(this.apiUrl + '/getCommunique').map((response) => {
    if (Object.keys(response.json()).length != 0) {
      return new Communique(response.json())
    } else {
      return {}
    }
  });
}

This is my Communique class:

export class Comunique {
  public id: number;
  public title: string;
  public content: string;
  public date: Date;
  public url: string;
  public imageUrl: string;

  constructor(input: ComuniqueRaw) {
    this.id = input.id;
    this.title = input.title;
    this.content = input.content;
    this.date = new Date(input.date.timestamp * 1000);
    this.url = 'url' + input.slug;
    this.imageUrl = 'url' + input.image;
  }
}

This works... But it seems like a workaround. Shouldn't the observable only return Communique objects? But if there is not an active communique, how would the Communique object be created? I mean, I can add a field with something like public exists: boolean; in the Communique class, but that seems like a workaround too (an object that only holds a single boolean ).

Am I handling it the right way? Or... How to handle an API response that might be an empty object with rxjs Observables?

The http.get() observable always returns once and only once. If the server responds with an empty object, it's not the http client's responsibility to ignore it - it's a valid http response.

I would say that your server should return a 404 if there is no communique object, and you catch that with an rxjs catchError, which would handle that case separately.

Edit:

If you would prefer to always return a 200 with either an empty response or an object, then the pattern you have implemented seems fine.

Edit2:

I've just noticed you're using the old .map() method. My catchError() answer would be for using the relatively new pipe operators.

getCommunique(): Observable<Communique> {
  return this.http.get(this.apiUrl + '/getCommunique').pipe(
    map(response => new Communique(response.json())),
    catchError(() => of(null))
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM