Ways to retrieve information from an Observable

I've been exploring how to retrieve data from an Observable object, and after some research, I've come across two main solutions. One is using subscribe (which isn't working for me or perhaps I'm using it incorrectly), and the other is map, which no longer exists. Just to clarify, I am using Nest.js.

My objective here is to directly return the variable `this.followers` populated with the response data.

Below 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 can I extract data from an Observable?

Answer №1

Even though the .toPromise method has been deprecated in RxJs 8, it is still functional in rxjs versions 7 and earlier. Give this a try:

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

Answer №2

After my inquiry from last night, I was able to discover two solutions. The first solution involves utilizing the pipe function (although I am still unclear on its functionality and would appreciate an explanation in the comments below) which results in the following code snippet:

  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;
        })
      )
  }

This way, nest can extract the response from the controller before forwarding it to the client.

The second approach that could be taken is similar to the one proposed by @KZoeps, with a slight modification due to the current limitations in using an async/await function without returning a Promise. Here is the updated code snippet: My aim here is to directly return the variable `this.followers` filled with the data from the response.

  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: []
        })
      }
    })
  }

I appreciate your assistance in any case. Thank you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the reason behind being unable to register two components with the same name using React Hook Form?

I have encountered an issue while using the useForm hook from React Hook Form library. Due to the specific UI library I am using, I had to create custom radio buttons. The problem arises when I try to register two components with the same name in the form ...

When compiling Node.js with TypeScript, Express handlebars are not copied to the dist folder as expected

Using Express and TypeScript has been a smooth experience for me. However, I encountered an issue when compiling with tsc - the views folder was not being copied into the dist folder as expected. In my SRC directory, there is a views folder containing two ...

Utilize Angular 5 to implement URL routing by clicking a button, while also preserving the querystring parameters within the URL

I have a link that looks like this http://localhost:4200/cr/hearings?UserID=61644&AppID=15&AppGroupID=118&SelectedCaseID=13585783&SelectedRoleID=0 The router module is set up to display content based on the above URL structure { path: & ...

Error: The request was not successful in creating and populating a list of type Microsoft.AspNetCore.Http.IFormFileCollection

I am encountering a Bad request error when trying to upload a file, convert it into JSON, and pass it to my .NET Core WebAPI controller. Below is an error screenshot that I received along with logging the model. https://i.sstatic.net/grSf4.png Here is m ...

Translating Angular2 content after successfully subscribing to a service

My parent component includes a child component and I aim to translate the text based on the user's language obtained from an API. Below is my translation pipe transform method: transform(value : string, args: any[]) : any { if (!value) return ...

Determine the data type of a parameter by referencing a prior parameter

Consider a scenario in my software where I have two distinct implementations of an Event Emitter. For instance: type HandlerA = (data: boolean) => void; type HandlerB = (data: number) => void; // HandlerB is somehow different from HandlerA type Eve ...

Encountered a TypeScript typing error when retrieving data from the Pinia state to populate the template

Having a type error when trying to pass data from the Pinia store to a child component's input field using TypeScript - Error message: 'Property 'storeForm' does not exist on type '{ $: ComponentInternalInstance; $data: {}; $prop ...

TS2355 Error: Functions must return a value if their declared type is not 'void' or 'any'

Currently, I am utilizing an authentication guard in Angular 5 to determine whether a user has permission to navigate to a specific page. However, I have encountered an issue related to returning an observable: The error states that a function with a decl ...

Circular structure error occurred when attempting to convert an object to JSON, starting at an object constructed with the constructor 'Object'

I am facing an issue where I need to update a Medico from the collection, and I have successfully destructured the data of the Medico's name and email. Additionally, I have obtained the ID of the assigned hospital. However, I am having trouble sendin ...

Implementing global variable sharing across components in Vue 3 using TypeScript while maintaining scope cleanliness: types, classes, and helper functions

Background I am currently developing a Vue application using the Composition API in TypeScript, encountering an issue that I have been unable to resolve. Despite my efforts, I am struggling to articulate the problem or find a solution. (For reference, I a ...

Issue with ng-maxlength directive

In my Angular 4 Application, I am attempting to implement validation for form inputs. Specifically, I want to restrict inputs with numbers to not accept more than 4 digits. If the input contains more than 4 digits, the form should be marked as invalid. I a ...

The @Input directive is not compatible with the OnPush change detection strategy

page.html <app-parcel-delivery-cost-promo [parcelDeliveryCost]="parcelDeliveryCost"> </app-parcel-delivery-cost-promo> page.ts changeDetection: ChangeDetectionStrategy.OnPush, parcelDeliveryCost: Partial<ParcelDeliveryCostModel>; ...

Leveraging File functionality in TypeScript

In the process of developing a web application with Angular 4 and Typescript, I encountered an issue while attempting to retrieve the date of a file for upload. Specifically, when trying to access the lastModified property of a File object, Typescript retu ...

The issue of Angular finalize not functioning when used within a pipe alongside switchMap

Once the user confirms, I want the process to begin and keep the modal busy until it's complete. However, the current code does not function in this manner. The isModalBusy condition only turns false when an HTTP error is returned from the service. In ...

Issue with Typescript: The 'remove' property is not found on the 'EventTarget' type

I keep seeing the error Type error: Property 'remove' is not recognized on type 'EventTarget'. <img onError={function(e) { e.target.remove(); }} src="../me.jpg" alt=""/> ...

Creating CSS from Angular stylesheets?

Are there any methods available to view the CSS corresponding to SCSS when using SCSS as the preprocessor for Angular? You can find a solution here: When using angular with scss, how can I see the translated css? The answer suggests using the --extract-c ...

Using an Angular if statement to validate the current route

I have a modal component that needs to display specific data depending on whether the user came from '/tabs/tab1' or '/tabs/tab2'. The issue is that both sets of data are currently being displayed in the modal component HTML, and the if ...

Creating localized versions of your React application is a breeze with i18next JSON mapping

Before anything else, please note that a translator is being used due to lack of proficiency in English. What is the best way to render a static i18next json file for multilingual support in a React application? Technologies used: React, Typescript, Styl ...

Steering clear of the generic Function type in React with TypeScript

Can anyone help me find a guideline that prohibits the use of "Function" as a type? myMethod: Function; I have searched but couldn't locate any information on this. Appreciate any suggestions :) ...

How to convert typescript path aliases into relative paths for NPM deployment?

I am currently working on a typescript project that utilizes paths for imports. For instance: "paths": { "@example/*": ["./src/*"], } This allows the project to import files directly using statements like: import { foo } from "@example/boo/foo"; Whe ...