Отправить данные из службы в наблюдаемый запрос Get

Я новичок в Angular и Observables. У меня есть служба, которая получает URL-адрес, который я хочу передать своим наблюдаемым и отображаемым данным каждый раз, когда ему передается новый URL-адрес с помощью NgFor. Любой пример поможет. Пожалуйста, помогите, ничего не работает. заранее спасибо

СЕРВИС файл

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Event } from '../event/event.interface';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})

export class ClientService {

  eventUrl ;

  constructor(private http: HttpClient) {
  }

 receiveEvent(eventId){
    this.eventUrl = eventId;
   console.log(this.eventUrl)
 }

renderEvent(eventUrl): Observable<Event[]>{
  return this.http
  .get<Event[]>(eventUrl)
}

ПОЛУЧЕНИЕ КОМПОНЕНТ файла

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ClientService } from '../service/clientService';
import { HttpParams, HttpClient } from '@angular/common/http';


@Component({
  selector: 'hero-review',
  templateUrl: './review.component.html',
  styleUrls: ['./review.component.css']
})
export class ReviewComponent implements OnInit {

public events = [];

  constructor(private _clientService: ClientService) { 
  }

  ngOnInit() {

    this._clientService.renderEvent('Need to be dynamic URL').subscribe(data => this.events = data);
  }
}

ОТПРАВКА КОМПОНЕНТ файл

sendEvent(eventId){
  let reqUrl = "myEndpoint" + eventId;
  this._clientService.receiveEvent(reqUrl);
}

person Jamal    schedule 09.02.2020    source источник
comment
Это выглядит прекрасно синтаксически. Не могли бы вы предоставить немного больше информации о конкретной области, с которой вы боретесь, включая примеры того, что вы пробовали до сих пор.   -  person Kurt Hamilton    schedule 09.02.2020
comment
Привет Курт, я обновил пример. Отправляющий файл отправляет URL-адрес службе. Сервис должен передать его Observable, сделав запрос GET. Каждый раз, когда передается URL-адрес, я хотел бы, чтобы Observable отображал запрошенные данные   -  person Jamal    schedule 09.02.2020
comment
Я до сих пор не понимаю, что здесь не работает. Загружается ли принимающий компонент в какой-то момент после того, как отправляющий компонент обновил URL-адрес в службе?   -  person Kurt Hamilton    schedule 09.02.2020
comment
Observable не получает динамический URL-адрес при передаче службе. Я не уверен, где это терпит неудачу. Каждый раз, когда отправляется URL-адрес, я хочу, чтобы он обновлялся   -  person Jamal    schedule 09.02.2020
comment
Я пробую ваш пример, но не могу определить, что такое тип субъекта. Нужно ли импортировать это?   -  person Jamal    schedule 09.02.2020
comment
Сам предмет в этом случае в порядке. Подписчики будут получать только те значения, которые были отправлены после того, как они подписались. Вы можете использовать ReplaySubject, чтобы гарантировать, что подписчики получат последнее выпущенное значение (если есть) при подписке. Это зависит от вашего варианта использования.   -  person Kurt Hamilton    schedule 09.02.2020
comment
Я также добавил пример того, как отказаться от подписки, так как вы захотите сделать это, чтобы избежать утечек памяти.   -  person Kurt Hamilton    schedule 09.02.2020


Ответы (1)


Кажется, я понимаю вашу проблему.

http.get(url) является одноразовым наблюдаемым. Это не поток, который может запускаться несколько раз, как субъекты. Вам нужно будет создать свою собственную тему и использовать ее в качестве прокси.

export class ClientService {

 constructor(private http: HttpClient) {
 }

 private eventPublisher: Subject<Event[]> = new Subject<Event[]>();

 receiveEvent(eventId){
   // call http client here, and publish results to event publisher
   const eventUrl = eventId;
   this.http.get<Event[]>(eventUrl).subscribe(response => {
     this.eventPublisher.next(response);
   });
 }

 renderEvent(eventUrl): Observable<Event[]>{
  // do not subscribe to http client here, subscribe to event publisher
  return this.eventPublisher.asObservable();
 }

Это шаблон проектирования pub-sub (издатель-подписчик). Может быть полезно прочитать о других решениях этого шаблона проектирования с использованием Angular, так как это довольно тривиальный пример.

Редактировать:

Вы также захотите отказаться от подписки в своем компоненте, как только вы закончите с подпиской, чтобы избежать утечек памяти.

Что-то вроде этого простого шаблона:

export class MyComponent implements OnInit, OnDestroy() {
  constructor(private myService: MyService) { }

  private destroyed: Subject<void> = new Subject<void>();

  ngOnInit(): void {
    this.myService.myMethod().pipe(
      takeUntil(() => this.destroyed)
    ).subscribe(() => { 
      // do stuff
    });
  }

  ngOnDestroy(): void {
    this.destroyed.next(undefined);
    this.destroyed.complete();
  }
}

Хотя это становится повторяющимся, если вам нужно начать делать это много. Я лично использую этот метод: https://stackoverflow.com/a/45709120/5367916

person Kurt Hamilton    schedule 09.02.2020
comment
myService не имеет myMethod? - person xinthose; 10.02.2020
comment
Это просто демонстрация шаблона в псевдокоде, а не реальная реализация. - person Kurt Hamilton; 10.02.2020