Передача данных от компонента к услуге 1. Служба 2 зависит от службы 1. Данные службы 2 к компоненту - PullRequest
0 голосов
/ 13 марта 2019

Я создаю приложение погоды.

У меня view.component, coord.service, weather.service.

У меня есть view.component для ввода пользователя. Я хочу передать ввод от компонента к coord.service, который выполняет вызов API и возвращает координаты. Координаты должны быть переданы в weather.service, который также вызывает API и возвращает Observable обратно в view.component для рендеринга в HTML. Я не могу понять / понять, как это сделать.

view.component.ts:

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

export class ViewComponent implements OnChanges {
  alerts: any;
  currData:any = {};

  @Input() location: string;

  coordinate = [];

  constructor(public weatherService: WeatherService) { }

  ngOnChanges(changes: SimpleChanges) {
    // pass location to coord.service -> i don't know what to do from here
    //this.weatherData(this.coordinate);
  }

  weatherData(coord: Array<number>) {
    this.weatherService.getWeatherInfo(coord).subscribe((data) => {
     // do something with data and make it render
    });
  }

coord.service

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

  readonly coord_API = ""

  constructor(private http : HttpClient) {  }

  getCoordinates(location : string) {
    return this.http.get(this.coord_API.replace("*", location)).pipe(
      tap(_ => console.log("recieved geoData")),
      catchError(err => {throw "GEO ERROR: " + err})
    )
  }
}

weather.service

@Injectable({
  providedIn: 'root'
})
export class WeatherService {
  readonly weather_api : string = "";
  coordinates : [] = [];
  // I need to pass in input from component to coordService
  constructor(public http : HttpClient, public coordinateService : CoordinateService) {  }

  getWeatherInfo(coordinates : Array<number>, type="daily") {
    return this.http.get(this.weather_api).pipe(
      tap(_ => console.log('got data')),
      catchError(err => {throw "WE. ERR : " + err})
    );
  }
}

1 Ответ

3 голосов
/ 13 марта 2019

Ваш компонент должен агрегировать сервисы и совершать звонки.

constructor(
  public weatherService: WeatherService,
  public coordsService: CoordinateService,
) { }

weatherData() {
  this.coordsService.getCoordinates('your param').pipe(
    switchMap(coords => this.weatherService.getWeatherInfo(coords))
  ).subscribe(data => console.log(data));
}

Услуги - это провайдеры, которым можно вводить что угодно в Angular. Они должны иметь единственную цель: компоненты должны быть в состоянии использовать их и комбинировать их.

switchMap является оператором RxJS.

RxJS - это библиотека, широко используемая Angular, которая позволяет реактивное программирование . Когда вы делаете HTTP-вызов, вы создаете наблюдателя, который создается через ключевое слово subscribe. Это создает поток, в котором данные неизменны.

RxJS позволяет вам использовать операторы для управления потоком. У вас есть множество операторов на выбор.

В случае switchMap: это оператор, который позволяет переключать поток на другой. Это означает, что сначала вы запрашиваете координаты, а затем используете switchMap для запроса погоды с результатом первого http-вызова.

Для этого у вас есть несколько операторов, например, mergeMap, flatMap ... Но switchMap всегда должен быть первым выбором, потому что он отменяет любой ожидающий запрос, если наблюдаемое снова становится наблюдаемым. Это означает, что пользователь отменяет ожидающий запрос, если он нажимает на кнопку несколько раз подряд, что приводит к уменьшению числа http-вызовов.

...