как подписаться на Observable, возвращаемый из службы данных сущности ngrx

У меня есть служба TransactionEntityService, производная от EntityCollectionServiceBase для модели Transaction.

export class TransactionEntityService
extends EntityCollectionServiceBase<Transaction> {

Я использую TransactionDataService, чтобы переопределить поведение DefaultDataService по умолчанию. В AppModule TransactionDataService регистрируется так

    export class AppModule {
  constructor(
    private eds: EntityDefinitionService,
    private entityDataService: EntityDataService,
    private transactionsDataService: TransactionsDataService
  ) {
    eds.registerMetadataMap(entityMetadata);

    entityDataService.registerService('Transaction', transactionsDataService);
  }
}

и TransactionsDataService переопределяет getAll, как показано ниже.

    export class TransactionsDataService extends DefaultDataService<Transaction> {
  constructor(
    http: HttpClient,
    httpUrlGenerator: HttpUrlGenerator,
    private notifyService: NotificationService
  ) {
    super('Transaction', http, httpUrlGenerator);
  }
  getAll(): Observable<Transaction[]> {
    return this.http
      .get<ApiResponse>('https://localhost:xxxx/transaction/GetLastSixMonth')
      .pipe(
        tap((data) => {
          this.notifyService.showSuccess(data.message, 'Sucess');
        }),
        map((res) => res.result),
        catchError((err) => {
          this.notifyService.showError(
            'Error While Six Month Transactions',
            'Error'
          );
          return of();
        })
      );
  }

Свойство $ entityie службы сущности возвращает правильный результат после вызова api. и я фильтрую этот результат, чтобы получить подсчет чего-либо в наблюдаемом с именем last6MonthDepositCount $.

  this.last6MonthDepositCount$ = this.transactionsEntityService.entities$.pipe(
  map((transactions) => {
    const res = transactions.filter(
      (transaction) =>
        transaction.transactionType === TransactionType.Deposit
    ).length;
    return res;
  })//,
 // tap((val) => this.depositCount = val)
);

в html я могу использовать этот наблюдаемый

{{ last6MonthDepositCount$  | async }}

оно работает.

что мне делать, чтобы использовать значение этой наблюдаемой в другой переменной в моем коде?

this.last6MonthDepositCount$.subscribe(x => this.dipositCount = x);

такой код не работает. я получаю 0 в dipositCount, который выглядит как начальное значение наблюдаемого.

введите описание изображения здесь


person Raas Masood    schedule 28.07.2020    source источник
comment
если {{last6MonthDepositCount $ | async}} работает, то .subscribe () также будет работать.   -  person abhay tripathi    schedule 28.07.2020
comment
Не могли бы вы рассказать, как вы используете этот счетчик депозитов? Кажется, есть проблема с реактивным подходом при использовании depositCount.   -  person abhay tripathi    schedule 28.07.2020
comment
я сделал это. last6MonthDepositCount $ .subscribe (x = ›{console.log (x);}); Я получаю два значения: 0, а затем 1, где 1 - это фактическое значение, которое я ищу.   -  person Raas Masood    schedule 28.07.2020
comment
Хорошо, поэтому я использую диаграмму ChartJS, где мне нужно установить 2 значения в круговой диаграмме. this.myChartData.data.datasets [0] .data = [this.depositCount, this.withdrawCount];   -  person Raas Masood    schedule 28.07.2020
comment
я обновил вопрос. выделенная строка - это та, которой я пытаюсь присвоить значения. У меня есть depositCount точно так же, как у меня widthdrawCount.   -  person Raas Masood    schedule 28.07.2020
comment
Проверьте ответ, возможно, вам придется настроить его в соответствии с вашим кодом.   -  person abhay tripathi    schedule 28.07.2020
comment
Конечно, ищу в нем   -  person Raas Masood    schedule 28.07.2020


Ответы (1)


Здесь реактивная парадигма вступает в противоречие с императивной парадигмой.

myChart.data.datasets[0].data вызывается до того, как this.last6MonthDepositCount$.subscribe(x => this.dipositCount = x); выдаст окончательное значение.

Что вам нужно сделать, это: - инициализировать chartJs с начальным значением / значением по умолчанию в ngAfterViewInit, а также обновить myChartData в методе this.last6MonthDepositCount$.subscribe().

Если вы хотите получить результаты из двух наблюдаемых вместе, используйте combLatest

const timerObservable1 = timer(0, 1000); 
    const timerObservable2 = timer(500, 1000); 
    const combinedTimers = combineLatest(timerObservable1, timerObservable2);
    combinedTimers.subscribe((value1, value2) => //DO something with both values together to update Chart);
person abhay tripathi    schedule 28.07.2020
comment
Как вы сказали, this.last6MonthDepositCount $ .subscribe (x = ›{console.log (x);}) дает два значения. Вот в чем проблема. построить диаграмму в методе .subscribe (). - person abhay tripathi; 28.07.2020
comment
но у меня есть два .subscribe, один для депозита и один для снятия, которые я должен использовать. и вы имеете в виду вот так this.last6MonthDepositCount $ .subscribe (x = ›{this.depositCount = x; this.myChartData.update ();}); ? myChartData уже определена в ngAfterViewInit - person Raas Masood; 28.07.2020
comment
Используйте combLatest, чтобы объединить результат обоих и построить в нем данные диаграммы. - person abhay tripathi; 28.07.2020
comment
Я понял, спасибо! Я делаю это так, как вы описали. Я делаю оба .subscribe внутри ngAfterViewInit, и оба .subscribe имеют this.myChartData.update (); в этом. - person Raas Masood; 28.07.2020