rxjs observable.pipe(take(1)) vs toPromise

Recently I’ve been moved to a new project which uses angular 6 as frontend framework and spring for REST services.

The project is in development for 2 years now and what I’ve observed was that almost all HTTP request made with angular HttpClient is then piped to take filter from rxjs. All REST APIs emit only one value. There’s no need for manual cancellation and the laziness property of observables.

My intuition is that using toPromise() would be a better way to code.

What are your thoughts?

  //customer-service.ts
  constructor(private http: HttpClient) {

  }

  public getCustomers() {
     return http.get('/customers');
  }

  //component.ts
  public ngOnInit() {
      this.customerService.getCustomers().pipe(take(1)).subscribe((customers) => {
           //do some stuff
      })
  }

My proposed approach:

  //customer-service.ts
  constructor(private http: HttpClient) {

  }

  public getCustomers() : Promise<Array<Customer>> {
     return http.get('/customers').toPromise();
  }

  //component.ts
  public ngOnInit() {
      this.customerService.getCustomers().then((customers: Array<Customer>) => {
         //do some stuff
      })
  }

I think that my approach is better because it is strongly typed and it’s cleaner.

Answer

Going from observables to promises is a step back.

It’s like going from a Porsche 911 to a Fiat multipla.

So no, you shouldn’t use toPromise(), and no, your way isn’t “better” (that’s some ego there buddy !)

I think that my approach is better because it is strongly typed and it’s cleaner.

Typing an HTTP answer isn’t depending on pormises or observables, but on the developer himself. And cleaner is a matter of perspective, personally I hate seeing toPromise()s.

And the major drawback of your solution is that once converted to a promise, you can’t pipe anything anymore, making your functions less versatile.

But their code isn’t the best either. Usually this kind of behavior is used for stores and caches, are you sure you didn’t omit something ?

Anyway, if not, and I only rely on the code provided, this would be the right code :

public getCustomers() {
  return http.get<Customer[]>('/customers');
}

....

public ngOnInit() {
  this.customerService.getCustomers()
    .subscribe((customers) => {...})
}

Leave a Reply

Your email address will not be published. Required fields are marked *