У меня проблема со службой в моем приложении. У меня есть сервис, в котором есть наблюдаемое. Этот наблюдаемый объект также содержит еще один наблюдаемый объект и две другие функции, которые обрабатывают данные из внутреннего наблюдаемого. Проблема в том, что когда я загружаю приложение в первый раз, я получаю значение undefined, потому что служба возвращает внешнее наблюдаемое до того, как будут выполнены внутренние наблюдаемые и функции изменения данных. Мне сказали, что я могу использовать для этого switchMap, но я очень запутался. Может ли кто-нибудь помочь, как использовать switchMap, чтобы внешний наблюдаемый объект ждал внутреннего наблюдаемого и функций, прежде чем возвращать какое-либо значение?

Так выглядит сервис:

  fetchFilteredReservations(filterBy: any, search: any): Observable<any> {
    this.reservation.fetchReservations().subscribe((data: any) => {
      const data1 = this.loopData(data)
      const data2 = this.switchData(data1, filterBy, search)
      this.filteredReservations = data2
    });
      return of(this.filteredReservations);
  }

  loopData(data: any) {
    let loopData = data
    loopData.forEach((element: any) => {
      let year: any = 0;
      let month: any = 0;
      let day: any = 0;
      day = element.createdDate.slice(0, 1);
      if (day < 10) {
        day = '0' + day;
      }
      month = element.createdDate.slice(2, 4);
      if (month < 10) {
        month = '0' + month;
      }
      year = element.createdDate.slice(5, 9);
      let date = `${year}-${day}-${month}`;
      element.createdDate = date;
      if (this.user === element.user) {
        element.canDelete = true;
      } else {
        element.canDelete = false;
      }
    });
    return loopData
  }

  switchData(data: any, filterBy: any, search: any){
    let filterData = []
    switch (filterBy) {
      case 'createdBy':
        return filterData = data.filter(
          (element: any) => element.user.includes(search)
        );
      case 'createdFor':
        return filterData = data.filter(
          (element: any) => element.reservedFor.includes(search)
        );
      case 'createdOn':
        return filterData = data.filter(
          (element: any) => element.createdDate.includes(search)
        );
      case 'reservedDate':
        return filterData = data.filter(
          (element: any) => element.reservedDateData.includes(search)
        );
      case 'desk':
        return filterData = data.filter(
          (element: any) => element.name.includes(search)
        );
    }
  }

Спасибо за любую помощь.

1
Tamás Köböl 16 Сен 2021 в 17:33

2 ответа

Лучший ответ

Я думаю, вам следует использовать оператор трубы. Я просто делал это на лету, но это выглядело бы так:

fetchFilteredReservations(filterBy: any, search: any): Observable<any> {
    return this.reservation.fetchReservations().pipe(
        map((data: any): any => 
            const data1 = this.loopData(data)
            const data2 = this.switchData(data1, filterBy, search)
            this.filteredReservations = data2
            return this.filteredReservations
        ),
    )
  }

док

1
tbarbot 16 Сен 2021 в 14:46

Я думаю, вам нужно что-то вроде этого:

fetchFilteredReservations(filterBy: any, search: any): Observable<any> {

    this.reservation.fetchReservations().pipe(
      switchMap((data: any) => {
          const data1 = this.loopData(data);
          const data2 = this.switchData(data1, filterBy, search);
          this.filteredReservations = data2;
          return data2; // or this.filteredReservations
      })
    );
}
2
FunkMonkey33 16 Сен 2021 в 15:07