1
votes

Récupérer les données de RxJS observables dans HttpModule

Je ne comprends pas comment mapper les propriétés des données hors de HttpService dans mon application NestJS. À ma connaissance, cet Observable enveloppe simplement axios . Voici un exemple de code:

interface Todo {
   task: string,
   completed: false
}

import {
  Injectable,
  HttpService,
  Logger,
  NotFoundException,
} from '@nestjs/common'
import { map } from 'rxjs/operators

async getTodo(todoUrl: string): Todo {
   const resp = this.httpService
      .get('https://example.com/todo_json')
      .pipe(map(response => response.data)) // map task/completed properties?
   return resp
}

resp dans ce cas semble être de type Observable . Comment puis-je récupérer uniquement les propriétés de données souhaitées en utilisant map sur cette demande pour renvoyer mon interface Todo ?


1 commentaires

Vous devez vous abonner à l'Observable.


3 Réponses :


1
votes

En regardant votre code:

  getTodo(): Observable<Todo> {
    return this.http.get<Todo>('https://example.com/todo_json')
      .pipe(
        map(response => response.data),
        catchError(this.handleError)
      );
  }

getTodo renvoie un Observable, pas la réponse. Donc, votre valeur de retour doit être Observable.

Le code devrait ressembler davantage à ceci:

import { map } from 'rxjs/operators' 

async getTodo(todoUrl: string): Todo {
   const resp = this.httpService
      .get('https://example.com/todo_json')
      .pipe(map(response => response.data)) // map task/completed properties?
   return resp
}

EDIT: Vous ne pouvez pas simplement renvoyer les données de cette méthode car elle est asynchrone. Il ne dispose pas encore des données. La méthode renvoie un Observable ... qui est essentiellement un contrat indiquant qu'il renverra (ultérieurement) les données pour vous.


3 commentaires

Je comprends qu'il renvoie un observable. Peut-être que j'ai besoin de clarifier ma question - je veux juste renvoyer un Todo, basé sur mon interface spécifiée dans la question. Je ne souhaite pas renvoyer un observable. Je veux récupérer ces données de l'Observable et les renvoyer à la place, comme le suggère l'interface de la méthode.


comment importer une carte ?


J'ai mis à jour l'exemple ci-dessus ... mais il semble que quelqu'un d'autre ait déjà répondu à votre question dans la réponse précédente.



3
votes

Par défaut, Nest s'abonnera à l'observable pour vous lorsque vous retournez l'Observable depuis votre service. Comme cela peut être le cas, vous pouvez faire quelque chose comme

@Injectable()
export class TodoService {

  constructor(private readonly http: HttpService) {}

  getTodos(todoUrl: string): Todo {
    const myTodo = await this.http.get(todoUrl).pipe(
      map(resp => resp.data),
    ).toPromise();
    return myTodo;
  }

}

Et tant que vous avez une classe de contrôleur appelant this.todoSerivce.getTodos (todoUrl) et la renvoyant , la réponse sera envoyée.

Cependant, si vous voulez plutôt en faire une promesse car vous y êtes plus habitué, vous pouvez ajouter un .toPromise () méthode à la chaîne observable et maintenant elle est en attente (bien qu'elle soit plus lente car elle doit attendre que l'observable émette son événement complet).

Exemple avec .toPromise () code >:

@Injectable()
export class TodoService {

  constructor(private readonly http: HttpService) {}

  getTodos(todoUrl: string): Observable<Todo> {
    return this.http.get(todoUrl).pipe(
      map(resp => resp.data),
    );
  }

}


6 commentaires

Où dans la documentation NestJS suggère-t-il que le framework s'abonne à Observables pour vous? De plus, y a-t-il un moyen de renvoyer uniquement le Todo avec les propriétés que je veux sans l'observable?


Il en parle dans la section asynchronicité du contrôleur . Comme je l'ai dit cependant, si vous voulez simplement retourner l'interface Todo sans renvoyer l'observable, appliquez un .toPromise () et attendez l'observable, en le définissant sur une constante (vous pouvez toujours effectuer les opérations map et pipe ). Ensuite, vous pouvez simplement renvoyer myTodo; . Je ferai une mise à jour pour montrer plus loin


C'est bien. Ça vous dérange si je demande comment utiliser la carte pour récupérer simplement les propriétés que je veux de resp ? dans ce cas, tâche et terminé?


Cela dépend un peu de ce qui est complètement renvoyé par l'API, et sans ces informations, il est difficile de dire comment cartographier les choses. Mais, map n'est qu'une fonction, vous pouvez donc l'étendre pour prendre une forme plus complète et faire les transformations dont vous avez besoin


comment importer une carte ?


@jim import {map} depuis 'rxjs / operators'



0
votes

Les fonctions Async doivent renvoyer une promesse, vous pouvez appeler toPromise sur une observable pour renvoyer une promesse.

async getTodo(todoUrl: string): Todo {
   const resp = this.httpService
      .get('https://example.com/todo_json')
      .pipe(map(response => response.data)) // map task/completed properties?
   return resp.toPromise();
}


0 commentaires