Наблюдаемая ошибка TypeScript при попытке выполнить несколько запросов к API (Angular, TypeScript, RxJS)

#angular #typescript #rxjs #observable

#angular #typescript #rxjs #наблюдаемая

Вопрос:

Я получаю эту ошибку:

 ERROR in src/app/fetch-trefle.service.ts:86:31 - error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.

86         mergeMap((item: any): Observable<any> => {
  

Вот мой код в моем сервисе:

 import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { Observable } from 'rxjs'
import { pluck, concatMap, mergeMap, map, filter, first, elementAt } from 'rxjs/operators'
import { of } from 'rxjs'

interface GrowthData {
  id: number
  common_name: string
  scientific_name: string
  growth: {
    minimum_precipitation: {
      mm: number
    }
    maximum_precipitation: {
      mm: number
    }
  }
}

@Injectable({
  providedIn: 'root'
})
export class FetchTrefleService {

  constructor(private http: HttpClient) { }
  plantId = 273225

  url = `https://trefle.io/api/v1/plants?token=${this.token}`
  growthUrl = `https://trefle.io/api/v1/plants/${this.plantId}?token=GTF4gOKNDJTmYmR2ut6r6y1fyD3pN1GrGSEoST_s0mA`

  proxyurl = 'https://cors-anywhere.herokuapp.com/'

  page = 'amp;page=1'

  id
  common_name
  scientific_name
  growth: {
    minimum_precipitation: {
      mm
    }
    maximum_precipitation: {
      mm
    }
  }


  fetchAllPlantData(): Observable<any> {
    return this.getPlantGrowth()
    return this.getPlantImageIdName()
  }

  getPlantImageIdName(): Observable<any> {
    return this.http.get(this.proxyurl   this.url   this.page)
      .pipe(
        pluck("data"),
      )
  }

  getPlantGrowth(): Observable<any> {
    return this.http.get(this.proxyurl   this.growthUrl   this.page)
      .pipe(
        pluck("data"),
        pluck("main_species"),
        mergeMap((item: any): Observable<any> => {
          this.id = of(item["id"]),
            this.common_name = of(item["scientific_name"]),
            this.scientific_name = of(item["scientific_name"]),
            this.scientific_name = of(item["scientific_name"]),
            this.growth.minimum_precipitation.mm = of(item["growth"]["minimum_precipitation"]["mm"]),
            this.growth.maximum_precipitation.mm = of(item["growth"]["maximum_precipitation"]["mm"])
        })
      )
  }
}
  

Вот мой код в компоненте:

 import { Component } from '@angular/core'


import { FetchTrefleService } from './fetch-trefle.service'

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  plants: any

  constructor(private fetchTrefleService: FetchTrefleService) { }

  getAllPlants() {
    this.fetchTrefleService.fetchAllPlantData().subscribe(res => {
      console.log(res)
      this.plants = res
    })
  }
}
  

Я пытаюсь сделать два запроса к API Trefle и собрать несколько значений из каждого ответа JSON. Он работал нормально, когда я выполнял отдельные запросы, когда я рефакторил для выполнения нескольких запросов, он выдавал ошибку TS вверху. Я предполагаю, что проблема связана с синтаксисом или чем-то, чего я не знаю о поведении или наблюдаемых и RxJS.

Спасибо!

Комментарии:

1. Функция fetchAllPlantData() выглядит странно.. вы не можете получить 2 возврата..

Ответ №1:

Вам необходимо вернуть observable из тела карты слияния.

 const click$ = fromEvent(document, 'click');

  click$
        .pipe(
                  mergeMap((e: MouseEvent) => {
                              return of({
                                        x: e.clientX,
                                        y: e.clientY,
                                        timestamp: Date.now()
                       });
                 })
             )
  

Комментарии:

1. Ага! Мне нужен был return . Вот код, который сработал: ` getPlantGrowth(): Observable<any> { return this.http.get(this.proxyurl this.growthUrl this.page) .pipe( pluck(«данные»), pluck(«main_species»), map((элемент: любой)=> { return [this.id , this.common_name, this.scientific_name, this.maximum_precipitation, this.minimum_precipitation] = [item.id , item.common_name, item.scientific_name, item.growth.maximum_precipitation.mm , item.growth.minimum_precipitation.mm ] }) ) }`

Ответ №2:

Вашему блоку mergeMap требуется возврат, который возвращает наблюдаемое.

Редактирование, потому что я неправильно нажал отправить

Я думаю, что вам нужно просто нажать или сделать. mergeMap ожидает получения наблюдаемого для продолжения потока.

Замените это своей картой слияния:

     tap((item: any) => 
          this.id = item.id
          ...
        )