Как подписаться на наблюдаемый объект только после того, как его данные были получены в Angular / NgRx?

#angular #observable #ngrx

#angular #наблюдаемый #ngrx

Вопрос:

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

У меня есть следующий код в ngOnInit() функции:

 ngOnInit() {
  this.store.select(getUsers)
  .pipe()
  .subscribe((users) => {
    this.navigateToNextStep(users.length > 0);  // navigates to correct page based on the boolean parameter
  });
}
  

И у меня есть следующая функция:

 nextClicked() {
  this.store.dispatch(MyActions.getUsers());
}
  

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

Каков правильный способ достижения моей цели, когда навигация будет происходить только тогда, когда список пользователей был активно извлечен щелчком мыши? Также обратите внимание, что список пользователей сохраняется в хранилище, поэтому мне нужно избегать любого непреднамеренного поведения в случае, когда пользователь возвращается на страницу после перехода.

Комментарии:

1. Но вы подписываетесь в ngOnInit ? Если вы хотите перемещаться только после щелчка, весь блок подписки из ngOnInit может быть перемещен в nextClicked() обработчик.

2. @MichaelD Вы, вероятно, правы. Однако на самом деле это не решит проблему, поскольку блок подписки и выборка данных являются асинхронными. Это означает, что подписка запускается сразу после nextClicked() вызова — до того, как серверная служба получит возможность вернуться с данными. Что мне нужно, так это способ подписки ПОСЛЕ получения данных.

3. Я не знаком с NgRX. Пожалуйста, скажите, какой оператор здесь возвращает данные из серверной службы. В текущем коде next обратный вызов подписки будет запущен только тогда, когда оператор this.store.select(getUsers) отправит уведомление.

4. Фактическая выборка данных из серверной части происходит в другом месте. Когда действие MyActions.getUsers() отправляется, оно перехватывается так называемым эффектом, который извлекает данные через службу. Затем данные передаются в редуктор, который обновляет состояние. Затем уведомление отправляется всем, кто наблюдает за этими данными через this.store.select(getUsers) селектор. Моя проблема в том, что, по-видимому, при подписке сразу выдается уведомление, и на данный момент мои данные еще не были извлечены.

5. @MichaelD прав, вы должны подписаться в nextClicked(). можете ли вы также поделиться кодом с уведомлением? Я полагаю, вам придется переместить его, чтобы это произошло после внутреннего вызова.

Ответ №1:

вы можете использовать .pipe(filter(data => !!data)) , чтобы пропустить начальное пустое значение из хранилища