Home > Back-end >  How to extract data from an Observable
How to extract data from an Observable

Time:11-21

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?

CodePudding user response:

although .toPromise is deprecated in RxJs 8, you can use it in rxjs versions 7 and below. So try this out:

async getFollowers(id: string): GithubFollower[] {
    const githubData = await this.httpService.get<GithubFollower[]>(`https://api.github.com/users/${id}/followers`).toPromise()
    this.followers = githubData.data
    return this.followers; // this.followers now returns the followers instead of undefined
  }

CodePudding user response:

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.

  • Related