Search code examples
angulartypescripthttprequest

It's ok to make an http call in an observable or it's better something else?


I made an http call inside an observable, do you think it is okay or should I split the two?

removeFav(movie:Movie){
this.getFavIdByMovie(movie).subscribe((data)=>{
  this.http.delete(`${this.baseURL}/favorites/${data[0].id}`).toPromise();
 });
}

another problem here is that i have a function with http request that return me an array of just 1 object and there is no possibility that return me more than 1 obj. How can i change the return into just the obj so in the first i can skip the data[0].id and write just data.id

getFavIdByMovie(movie:Movie){
  let userId = this.authSrv.getUserId();
  return this.http.get<Favorite>(`${this.baseURL}/favorites?userId=${userId}&movieId=${movie.id}`);
}

Solution

  • This is not recommended to call an observable inside another's subscribe block. What you could do here is the following:

    removeFav(movie: Movie) {
      return this.getFavIdByMovie(movie).pipe(
        switchMap((data) => this.http.delete(`${this.baseURL}/favorites/${data[0].id}`)
      )
    }
    

    Here, you are converting one stream into another through the use of switchMap operator. So you will have to subscribe to the removeFave(movie) stream to actually delete it (because unless you subscribe, it is in a cold state). An example usage:

    onClickDelete() {
      this.removeFav(this.movie).subscribe({
        next: () => this.showAlert('Deleted');
      })
    }
    

    Second part To unwrap a single object from the array of objects, you can use a map operator from RxJS.

    getFavIdByMovie(movie: Movie): Observable<Favorite> {
      let userId = this.authService.getUserId();
      return this.http
        .get<Favorite>(`${this.baseURL}/favorites?userId=${userId}&movieId=${movie.id}`)
        .pipe(
           map((results) => results?.[0])
        )
    }
    

    Now, you will get a single object instead of an array.