2017-02-28 6 views
0

의 출력과 2 스트림을 실행, 그것은에서 그리고 관찰 가능한RxJS 내가 위치를 결정하는 서비스를 가지고 최초의 스트림

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs'; 

const GEOLOCATION_ERRORS = { 
    'errors.location.unsupportedBrowser': 'Browser does not support location services', 
    'errors.location.permissionDenied': 'You have rejected access to your location', 
    'errors.location.positionUnavailable': 'Unable to determine your location', 
    'errors.location.timeout': 'Service timeout has been reached' 
}; 

@Injectable() 
export class GeolocationService { 
    public getLocation(opts): Observable<any> { 
     return Observable.create(observer => { 
      if (window.navigator && window.navigator.geolocation) { 
       window.navigator.geolocation.getCurrentPosition(
        (position) => { 
         observer.next(position); 
         observer.complete(); 
        }, 
        (error) => { 
         switch (error.code) { 
          case 1: 
           observer.error(GEOLOCATION_ERRORS['errors.location.permissionDenied']); 
           break; 
          case 2: 
           observer.error(GEOLOCATION_ERRORS['errors.location.positionUnavailable']); 
           break; 
          case 3: 
           observer.error(GEOLOCATION_ERRORS['errors.location.timeout']); 
           break; 
         } 
        }, opts); 
      } else { 
       observer.error(GEOLOCATION_ERRORS['errors.location.unsupportedBrowser']); 
      } 
     }); 
    } 
} 

export var GeolocationServiceInjectables: Array<any> = [ 
    { provide: GeolocationService, useClass: GeolocationService } 
]; 

로 쓰여 내 HttpService를 내가 출력과 쿼리 URL을 구성 할 위치 서비스에서

import { Observable } from 'rxjs/Observable'; 
import { Injectable, Inject } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import { GeolocationService } from './location.service'; 
import { WeatherItem } from '../weather-item/weather-item.model'; 

export const OpenWeatherMap_API_KEY: string = 'SOME_API_KEY'; 
export const OpenWeatherMap_API_URL: string = 'http://api.openweathermap.org/data/2.5/forecast'; 

@Injectable() 
export class HttpService { 
    constructor(private http: Http, 
     private geolocation: GeolocationService, 
     @Inject(OpenWeatherMap_API_KEY) private apiKey: string, 
     @Inject(OpenWeatherMap_API_URL) private apiUrl: string) { 
    } 

    prepaireQuery(): void { 
     this.geolocation.getLocation({ enableHighAccuracy: false, maximumAge: 3 }).subscribe(
      (position) => { 
       let params: string = [ 
        `lat=${position.latitude}`, 
        `lon=${position.longitude}`, 
        `APPID=${this.apiKey}`, 
       ].join('&'); 
       // return `${this.apiUrl}?${params}`; 
      } 
     ); 

    } 

    getWeather(): Observable<WeatherItem[]> { 
     return this.http.get(/*there should be the url*/) 
      .map((response: Response) => { 
       return (<any>response.json()).items.map(item => { 
        const city = { 
         city: item.city.name, 
         country: item.city.country, 
        } 
        return item.list.map(entity => { 
         return new WeatherItem({ 
          temp: entity.main.temp, 
          temMin: entity.main.temp_min, 
          temMax: entity.main.temp_max, 
          weatherCond: entity.weather.main, 
          description: entity.weather.description, 
          windSpeed: entity.wind.speed, 
          icon: entity.weather.icon, 
          city, 
         }) 
        }) 
       }) 
      }) 
    } 
} 
export var HttpServiceInjectables: Array<any> = [ 
    { provide: HttpService, useClass: HttpService }, 
    { provide: OpenWeatherMap_API_KEY, useValue: OpenWeatherMap_API_KEY }, 
    { provide: OpenWeatherMap_API_URL, useValue: OpenWeatherMap_API_KEY } 
]; 

질문은 요청하기 전에 URL을 얻는 방법입니다. 나는 unsubscribe()를 가진 해결책을 보았습니다. 그러나 나는 thay가 그렇게 좋지 않다고 생각합니다. 나는 merge()에 대해서 생각해 봤지만 그것이 정말로 원하는 것인지 확신하지 못합니다.

답변

1

아마도 RxJ의 mergeMap 연산자를 찾고있을 것입니다.

무엇을 mergeMap가 자동으로 소스 관찰 가능에 가입하고, 그 결과를 내측 관찰 가능으로 작업하게하고, 마지막으로 출력을 평평하게합니다.

이 예에서

, 당신은 firstUrl를 호출하고 secondUrl에 두 번째 호출에서 해당 요청에서 얻는 결과를 사용

this.http.get(`{firstUrl}`) 
    .mergeMap(res => this.http.get(`{secondUrl}/{res.json()}`)) 
    .subscribe(...) 

난 당신의 코드는 특정하지 않았, 아니에요으로 정확히 무엇을하고 싶은지 확신하십시오. 그러나 나는 이것이 당신을 도중에 도울 것이기를 바란다! 이것은 사용하여 수행 할 수 있습니다

+0

그것은 작동)) 감사합니다) –

1

map/flatMap 조합 :

getWeather(): Observable<WeatherItem[]> { 
    return this.geolocation.getLocation({ enableHighAccuracy: false, maximumAge: 3 }) 
     .map((position) => { 
      let params: string = [ 
       `lat=${position.latitude}`, 
       `lon=${position.longitude}`, 
       `APPID=${this.apiKey}`, 
      ].join('&'); 
      return `${this.apiUrl}?${params}`; 
     }) 
     .flatMap(url => this.http.get(url) 
     .map((response: Response) => { 
      return (<any>response.json()).items.map(item => { 
       const city = { 
        city: item.city.name, 
        country: item.city.country, 
       } 
       return item.list.map(entity => { 
        return new WeatherItem({ 
         temp: entity.main.temp, 
         temMin: entity.main.temp_min, 
         temMax: entity.main.temp_max, 
         weatherCond: entity.weather.main, 
         description: entity.weather.description, 
         windSpeed: entity.wind.speed, 
         icon: entity.weather.icon, 
         city, 
        }) 
       }) 
      }) 
     }) 
} 
+0

그냥 참고; 'flatMap'은'mergeMap'으로 이름이 바뀝니다. 'flatMap'은 여전히 ​​작동하지만,'mergeMap '의 별명입니다. –

관련 문제