简体   繁体   English

订阅可观察

[英]Subscription to Observable

I have an Angular app where I retrieve data from API using HttpClient. 我有一个Angular应用,使用HttpClient从API检索数据。

I would like to get raw data from API and sent them to corresponding service. 我想从API获取原始数据并将其发送到相应的服务。 The services has methods that map raw data to model objects and return them to the component. 这些服务具有将原始数据映射到模型对象并将其返回给组件的方法。

The problem is, I get the data from API (return Observable), I subscribe in the service method and then I do not know how to pass data to the component. 问题是,我从API获取数据(返回Observable),我订阅了service方法,然后我不知道如何将数据传递给组件。

Api service where I retrieve data from API. 我从API检索数据的api服务。 Then I send raw data and Hotel service where I want to map raw data to model and send to the component 然后,我发送原始数据和酒店服务,并在其中映射原始数据以进行建模并发送到组件

@Injectable()
export class ApiService {
  ...
  public getHotelById(hotelId: number): Observable<any> {
      return this.http
          .get(API_URL + '/hotel/' + hotelId)
          .map((response) => {
              return response;
          })
  }
  ...
}


@Injectable()
export class HotelService {
  ...
  public getHotelById(id: number): Subscription {
    return this.api.getHotelById(id).subscribe(
        (response) => {
            let hotel = new HotelModel(response.hotel);

            hotel.mapCountry(response.country);

            return hotel;
        }
    );
  }
  ...
}

Can anyone help me how to retrieve datafrom service in the component? 谁能帮助我如何从组件中的服务检索数据? Im getting error that object which hotelservice returns is subscription and I cannot subscribe to it. 我收到错误消息,hotelservice返回的对象是订阅,我无法订阅。

Is there any way how to do this? 有什么办法吗? I do not want to do some business logic in the API service. 我不想在API服务中做一些业务逻辑。 On that place I just want to retrieve data. 在那个地方,我只想检索数据。

Component method 组成法

  ngOnInit() {
    this.activatedRoute.queryParamMap.subscribe(
        (map) => {
            this.hotelId = this.activatedRoute.snapshot.params['id'];

            this.hotel = this.hotelService.getHotelById(this.hotelId)
                .subscribe(
                (hotel) => {
                  this.hotel = hotel;
                }
            )
        }
    )
  }

map your response instead of subscribing to it. map您的响应,而不是订阅它。 Subscriptions are the "end of the road", while mapping is just "changing lanes". 订阅是“道路的尽头”,而地图只是“变道”。

export class HotelService {
  ...
  public getHotelById(id: number) {
    return this.api.getHotelById(id).pipe(map(
        (response) => {
            let hotel = new HotelModel(response.hotel);

            hotel.mapCountry(response.country);

            return hotel;
        }
    ));
  }
  ...
}

I think a good way for you is to map your result in the specific function "getHotelById" (You make an ORM like) 我认为对您来说,一种好的方法是将结果映射到特定的函数“ getHotelById”中(您可以像创建ORM)

@Injectable()
export class ApiService {
  ...
  public getHotelById(hotelId: number): Observable<any> {
      return this.http
          .get(API_URL + '/hotel/' + hotelId)
          .map((response) => {
            let hotel = new HotelModel(response.hotel);

            hotel.mapCountry(response.country);

            return hotel;
          })
  }
  ...
}


@Injectable()
export class HotelService {
  ...
  public getHotelById(id: number): Observable<any> {
    return this.api.getHotelById(id);
  }
  ...
}

And in your component nothing change. 在您的组件中,没有任何变化。

Do you really need two services? 您真的需要两项服务吗?

@Injectable()
export class HotelService extends AbstractHttpService {

  constructor (
    private httpClient: HttpClient,
  ) {
    super();
  }

  loadHotels(): Observable<Hotel[]> {
    const url = this.url('hotels');

    return this.httpClient.get<Hotel[]>(url, this.standardHttpOptions);
  }
}

The abstract class has some helpers for querying the target URL and provides standard http options for the get call. 抽象类具有一些用于查询目标URL的帮助程序,并为get调用提供了标准的http选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM