Angular типы слияния RxJSMap

Попытка получить долготу и широту из службы геолокации в list.service, используя URL-адрес запроса http.get.

Первая проблема:

businesses Property 'businesses' does not exist on type '{}'

Цените помощь по этому вопросу и время

list.service.ts:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { List } from '../models/list.model';
import { map } from 'rxjs/operators';
import { GeolocationService } from '../services/geolocation.service';
import { mergeMap } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ListService {
    private serverApi = 'http://localhost:3000';

    constructor(private http: HttpClient, private geoServ: GeolocationService) { }

    public getAllLists(): Observable<List[]> {
        return this.geoServ.getGeoLocation().pipe(
          mergeMap<{businesses: List[]}>(({ latitude, longitude }) =>             
            this.http.get(`${this.serverApi}/yelp/${longitude}/${latitude}`).pipe(
            )
          ),
          map(res => res.businesses));
    }
}

geolocation.service.ts:

import { Injectable } from '@angular/core';
import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent, SubscriptionLike, PartialObserver } from 'rxjs';
@Injectable({
  providedIn: 'root'
})
export class GeolocationService {

  constructor() { }

  getGeoLocation() {
    return new Observable((observer) => {
      console.info('Geolocation working!');
      const options = {
        enableHighAccuracy: true,
        timeout: 5000,
        maximumAge: 0
      };
      const success = (pos) => {
        const crd = pos.coords;
        console.info(`Longitude : ${crd.longitude}`);
        const location = {
          "latitude" : crd.longitude,
          "longitude": crd.longitude
        };
        observer.next(location);
        observer.complete();
      };
      const error = (err) => {
        console.warn(`ERROR(${err.code}): ${err.message}`);
        observer.error(err);
        observer.complete();
      };
      navigator.geolocation.getCurrentPosition(success, error, options);
    });  
  }
}

list.model.ts:

export interface List {
    id: string;
    name?: string;
    rating?: number;
    review_count?: number;
    url?: string;
    location: string;
    display_name?: string;
    image_url?: string;
    is_closed?: boolean;
}

Добавлен model.ts, чтобы помочь прояснить

getGeoLocation ничего не возвращает, поэтому вам нужно вернуть свой наблюдаемый
user184994 24.08.2018 20:33

спасибо, что исправили проблему с трубой, все еще есть проблема с предприятиями

Jaime Moncayo 24.08.2018 20:35

Попробуйте this.http.get<any>(`${this.serverApi}/yelp/${longitude}/${la‌​titude}`) в list.service.ts (или, если у вас есть интерфейс для типа ответа, используйте его вместо any)

user184994 24.08.2018 20:37

вернуть this.geoServ.getGeoLocation (). pipe (mergeMap (({latitude, longitude}) => this.http.get <List []> (${this.serverApi}/yelp/${longitude}/${‌​latitude})), map (res => res.busshops) Я получаю сообщение об ошибке все еще с предприятиями, а <List []> говорит, что ожидаемых аргументов типа 0, но получено 1.

Jaime Moncayo 24.08.2018 20:42

При копировании / вставке приведенного выше кода я вижу несколько ошибок, но List[] не будет иметь свойства businesses (хотя отдельный List может быть, как он должен себя вести с учетом этого?

user184994 24.08.2018 20:51

yelp передает {"предприятия": [], "всего": 3000, "регион": {"центр": {"долгота": xxxx, "широта": xxxx}}}, а массив предприятий содержит 3000 предприятий и их подробности

Jaime Moncayo 24.08.2018 21:02

Я добавил ответ ниже, который тогда должен сработать.

user184994 24.08.2018 21:03

@JaimeMoncayo Я рад, что вы нашли решение, но, пожалуйста, отредактируйте заголовок вопроса, потому что он слишком широкий. Сделайте его более конкретным для вашего случая, чтобы помочь поисковым системам правильно отображать ваш вопрос в результатах. Спасибо

shohrukh 26.08.2018 00:40
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
3
8
778
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, вы все еще используете старый HTTP-клиент angular. Это тоже плохо работает с набором текста. Чтобы исправить типизацию, добавьте объект типа к универсальному параметру mergeMap.

public getAllLists(): Observable<List[]> {
  return this.geoServ.getGeoLocation().pipe(
    mergeMap<{latitude: string, longitude: string}, {businesses: List[]}>(({ latitude, longitude }) =>             
      this.http.get(`${this.serverApi}/yelp/${longitude}/${latitude}`).pipe(
        map(res => res.json()), // remove after updating to new http client
      )
    ),
    map(res => res.businesses));
}

Извините за то, что я обновил его сейчас и код выше! С объектом типа я получаю ошибки: ОШИБКА в src / app / services / list.service.ts (19,11): ошибка TS2558: ожидаются 2-3 типовых аргумента, но получено 1. src / app / services / list .service.ts (23,26): ошибка TS2339: свойство «business» не существует для типа «{}».

Jaime Moncayo 24.08.2018 20:57

@JaimeMoncayo Я обновил свой ответ. Я забыл, что mergeMap имеет два общих типа. Лучше не использовать any для обеспечения безопасности типов

Poul Kruijt 24.08.2018 21:32
Ответ принят как подходящий

Ваш код говорит, что ваш GET возвращает List[], но у массива не будет свойства businesses, поэтому он жалуется. Вы можете использовать:

  public getAllLists(): Observable<List[]> {
    return this.geoServ.getGeoLocation().pipe(
      mergeMap(({ latitude, longitude }) =>
        this.http.get<any>(`${this.serverApi}/yelp/${longitude}/${latitude}`)
      ),
      map(res => res.businesses));
  }

Это будет компилироваться, но если ответ действительно является массивом, Observable может в конечном итоге выдать undefined.

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