Search code examples
angulartypescriptrxjsnest

How to extract data from an Observable


I'm trying to understand how to extract data from an object of type Observable, after not some research I fall mainly on two solutions. subscribe (which does not work in my case or which I use badly), or map which does not exist any more. I specify I use nest.

here my goal is to be able to directly return the variable this.followers filled with the data of the answer

Here is my code.

import { HttpService } from '@nestjs/axios';
import { Injectable } from '@nestjs/common';
import { GithubFollower } from './../../../../shared/github.models'

@Injectable()
export class GithubService {
  private followers: GithubFollower[]

  constructor(private httpService: HttpService) {}

  getFollowers(id: string): GithubFollower[] {
    this.httpService.get<GithubFollower[]>(`https://api.github.com/users/${id}/followers`)
      .subscribe(data => {
        this.followers = data.data // this.followers = my data
        console.log(this.followers); // print my data
      });
    console.log("here", this.followers); // print "here undefined"
    return this.followers; // this.followers = []
  }
}

How do I extract data from an Observable?


Solution

  • following my question of yesterday evening, I found two solutions. The first one is to use the pipe function (even if I don't understand well what it does, I would be happy to have an explanation in the comments of this post) which gives us this:

      getFollowers(id: string): Observable<DashBoardResponse> {
        return this.httpService
          .get<GithubFollower[]>(`https://api.github.com/users/${id}/followers`)
          .pipe(
            map(res => {
              const response: DashBoardResponse = {
                code: res.data !== [] ? 200 : 400,
                message: res.data !== [] ? 'success' : 'Possible bad id',
                response: res.data
              }
              return response;
            })
          )
      }
    

    then nest is able to extract the response from the controller before sending it back to the client.

    The second solution that I could have is the one of @KZoeps a little bit modified, because on the current version of nest it is not possible to use an async/await function without returning a Promise. Here is the code: here my goal is to be able to directly return the variable this.followers filled with the data of the answer

      async getFollowers(id: string): Promise<DashBoardResponse> {
        this.followers = await (await this.httpService.get<GithubFollower[]>(`https://api.github.com/users/${id}/followers`).toPromise()).data
        return new Promise((resolve, reject: (reason?: DashBoardResponse) => void) => {
          if (this.followers !== []) {
            resolve({
              code: 200,
              message: 'success',
              response: this.followers
            });
          } else {
            reject({
              code: 400,
              message: 'Possible bad id',
              response: []
            })
          }
        })
      }
    

    Thank you in any case for your help.