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.