Возврат данных из ответа в наблюдаемом в Nestjs

Я новичок в Nestjs , Typescript и в основном бэкэнд-разработке. И я работаю над простым приложением Weather, где я получаю данные о погоде из Open Weather API. Я использую встроенный Nest HttpModule, который оборачивает Axios внутри, а затем использует HttpService для отправки GET-запроса к Open Weather. Запрос возвращает Observable, что для меня совершенно новость. Как извлечь фактические данные ответа из наблюдаемого в Injectable service и вернуть их в Controller?

Вот моя погода.service.ts

import { Injectable, HttpService } from '@nestjs/common';

@Injectable()
export class AppService {
  constructor(private httpService: HttpService) {}

  getWeather() {
    let obs = this.httpService.get('https://api.openweathermap.org/data/2.5/weather?q=cairo&appid=c9661625b3eb09eed099288fbfad560a');
    
    console.info('just before subscribe');
    
    obs.subscribe((x) => {
        let {weather} = x.data;
        console.info(weather);
    })
    console.info('After subscribe');
    
    // TODO: Should extract and return response data f
    // return;
  }
}

А это Weather.controller.ts

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getWeather() {
    const res = this.appService.getWeather();
    return res;
  }
}

Также может кто-нибудь уточнить, какие типы отсутствуют в моем коде?

Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
5
0
10 312
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

RxJS Observables по сути являются расширенными обратными вызовами. Поскольку они работают асинхронно, вам нужно, чтобы ваш код учитывал это. Nest может обработать, если Observable будет возвращен из контроллера и подпишется на него под капотом для вас, поэтому все, что вам нужно сделать в своем сервисе, это что-то вроде этого:

import { Injectable, HttpService } from '@nestjs/common';

@Injectable()
export class AppService {
  constructor(private httpService: HttpService) {}

  getWeather() {
    return this.httpService.get('https://api.openweathermap.org/data/2.5/weather?q=cairo&appid=c9661625b3eb09eed099288fbfad560a').pipe(
      map(response => response.data)
    );
   
  }
}

map импортируется из rxjs/operators и похож на Array.prototype.map тем, что может принимать значения и преобразовывать их по мере необходимости. Отсюда ваш Controller просто должен вернуться this.appService.getWeather(), а Nest позаботится обо всем остальном.

Другой вариант, который у вас есть, — преобразовать наблюдаемое в обещание с помощью .toPromise(), а затем вы можете использовать свой обычный синтаксис async/await, что является еще одним допустимым выбором.


RxJS v7 и выше

toPromise() устарела в RxJS v7. Теперь рекомендуется использовать lastValueFrom(observable) или firstValueFrom(observable) вместо наблюдаемой асинхронности.

Спасибо, я уже разобрался и преобразовал toPromise(), что упростило использование async/await

Seif A. 10.12.2020 20:38

По состоянию на середину 2022 года toPromise() устарела. RxJS рекомендует использовать либо lastValueFrom(), либо firstValueFrom(). rxjs.dev/deprecations/to-promise

Michael Jay 20.07.2022 04:41

Другие вопросы по теме