-1

I've just finished my Angular lessons and I already find out some differences between what I learn and the Angular official documentation.

Let's imagine I want to recover an user with ID of an API.

Here is how I would do it according to my lessons :

export class UserService {

  constructor(
    private httpClient: HttpClient
  ) {
  }

  public user: User; // local variable using User model
  public userSubject: BehaviorSubject<User> = new BehaviorSubject<User>(null);

  async getSingleUserFromServer() {
    await this.httpClient.get<any>('https://xvalor.repliqa.fr/api/v1/user/' + this.userId).subscribe(
      (response) => {
        this.user = response;
        this.userPortfolios = this.user.portfolioAssoc;
        this.emitSubjects();
      });
  }

  emitSubjects() {
    this.userSubject.next(this.user);
  }
}

and here is how angular doc procceed

getHeroes (): Observable<Hero[]> {
  return this.http.get<Hero[]>(this.heroesUrl)
    .pipe(
      tap(_ => this.log('fetched heroes')),
      catchError(this.handleError<Hero[]>('getHeroes', []))
    );
}

I understand than both methods are quiet doing the same thing, I just want to be sure which one I should use, especially in big project developpement.

dsan
  • 3
  • 1
  • 3
DrK
  • 144
  • 1
  • 10
  • You should definitely not await observables. – Roberto Zvjerković Feb 26 '20 at 12:20
  • 2
    This is not really a question for here... but I'll comment from my own expertise. First, your example of lessons is wrong. You are using `await` for a subscription? That's not possible. You should use the `toPromise()`. But then again, never use `toPromise()`. Angular is using rxjs thoroughly, and it is really advised you would do too. In a big project development, you should even look at using some sort of reactive store mechanism, like ngrx or ngxs or any other out there. With this you can make your dataflow more organized and easier to maintain and test – Poul Kruijt Feb 26 '20 at 12:21
  • Official content is good practice to use `rxjs` rather than `async-await` in angular application – Developer Feb 26 '20 at 12:26
  • 1
    You should really have gone through the tour of heros as your tutorial – Nabel Feb 26 '20 at 12:48

3 Answers3

1

I would stick to the second approach as it is more generic and it uses Observable. Observale allow to emit any count of events and callback will be called for each event. Promise generates a single event after completion.

In addition, service class should not have async and await parts. The goal of service is to return data and UI component can consume data using async and await parts. async and await are syntactic sugar to avoid writing .subscribe part as it is really verbose. So write async and await in your UI components.

If you want to use Promise, then your service should not have subscribe part:

getSingleUserFromServer() {
    return this.httpClient.get<any>('https://xvalor.repliqa.fr/api/v1/user/' + this.userId);
}

However, it is better to return Observables from your service.

StepUp
  • 36,391
  • 15
  • 88
  • 148
1

Your first approach is flawed in that the consumer must perform two separate operations: call getSingleUserFromServer() to make the call, and subscribe to UserService.user to consume the results. And in case of errors, he won't receive any feedback.

Stick to the official guidelines for now. BTW, if your goal was to additionally store the user as a variable available to everyone, then with the Observable pattern it's as simple as adding another tap to the pipe:

httpClient.get(url)
    .pipe(
        someOperator(),
        tap(user => this.user = user),
        anotherOperator(...someArgs),
    )
mbojko
  • 13,503
  • 1
  • 16
  • 26
0

Observables and Subjects are two diffrent objects from rxjs and bring diffrent properties with them. The answers to this question show some of the key differences: What is the difference between a Observable and a Subject in rxjs?

Supporterino
  • 181
  • 9