У меня есть ситуация, я не знаю, как обращаться. Ситуация заключается в том, чтобы долго вытащить Firebase, получить некоторые данные как наблюдаемые обратно к ngrx/effects, а затем снова вызвать Firebase, чтобы удалить некоторые данные, а затем, наконец, передать первые данные о возврате Firebase в Action для редуктора, чтобы выполнить свою задачу.Стратегии связывания операций RXJS в ngrx/эффектах для вызова Firebase для различных операций до вызова действия
Вот код ngrx/эффекты
constructor(private threadsService: ThreadsService, private store: Store<ApplicationState>) {
}
@Effect() newMessages$ = Observable.interval(5000)
.withLatestFrom(this.store.select("uiState"))
.map(([any,uiState]) => uiState)
.do(console.log)
.filter(uiState => uiState.userId)
.switchMap(uiState => this.threadsService.loadNewMessagesForUser(uiState.userId))
.withLatestFrom(this.store.select("uiState"))
.do(console.log)
.switchMap(([messages, uiState]) => this.threadsService.deleteMessagesQueuePerUser(messages, uiState.userId))
.map(messages => new NewMessagesReceivedAction(messages))
Первый this.threadsService.loadNewMessagesForUser (uiState.userId) получит Firebase данные я в конце концов нужно для NewMessagesReceivedAction (сообщений). Но перед тем, как я передаю сообщение видимым, мне также нужно удалить MessageQueuePerUser, чтобы следующий интервал возвращался пустым, поскольку новое сообщение уже было вытащено. Но приведенный выше код не будет работать, и имеет обалденный результат и много ошибок:
ОШИБКА # 1: без .Не (console.log) перед фильтром, этот код
.filter(uiState => uiState.userId)
выдаст ошибку в WebStorm - Свойство 'идентификатор пользователя' не существует на типа '{}')
ERROR # 2: эти 3 строки просто не будет работать:
// .withLatestFrom(this.store.select("uiState"))
// .do(console.log)
// .switchMap(([messages, uiState]) => this.threadsService.deleteMessagesQueuePerUser(messages, uiState.userId))
идея этих 3 линий продолжать. передать сообщение наблюдаемым вниз, но мне также нужно, чтобы uiState.userId удалял некоторые данные в Firebase, используя это: this.threadsService.deleteMessagesQueuePerUser (сообщения, uiState.userId). Но наблюдаемые сообщения в первом списке Firebase не опускаются во второй. Вот код threadsService:
firebaseUpdate(dataToSave) {
const subject = new Subject();
this.sdkDb.update(dataToSave)
.then(
val => {
subject.next(val);
subject.complete();
},
err => {
subject.error(err);
subject.complete();
}
);
return subject.asObservable();
}
loadNewMessagesForUser(uid: string): Observable<Message[]> {
console.log ("We are pulling the server! uid: " + uid);
return this.findMessagesForMessageKeys(this.findMessageKeysPreUserUnread(uid));
}
findMessagesForMessageKeys(messageKeys$:Observable<string[]>): Observable<Message[]> {
return messageKeys$
.map(pspp => pspp.map(messageKey => this.db.object('message/' + messageKey)))
.flatMap(fbojs => Observable.combineLatest(fbojs))
}
deleteMessagesQueuePerUser(messages:Observable<Message[]>, uid:string): Observable<Message[]> {
let dataToSave = {};
dataToSave['MessagesQueuePerUser/' + uid] = null;
this.firebaseUpdate(dataToSave);
return messages;
}
findMessageKeysPreUserUnread(uid: string):Observable<string[]> {
return this.db.list('MessagesQueuePerUser/' + uid)
.map(getKeys => getKeys.map(p => p.$key));
}
Может кто-нибудь мне точку в правильном направлении, чтобы выяснить, как структурировать и писать это право?
ОБНОВЛЕНИЕ для уточнения.
Да У меня есть тип UiState. И я действительно хочу получить NewMessages из this.threadsService.loadNewMessagesForUser (uiState.userId). ПОСЛЕ того, как я получаю NewMessages (так как это наблюдаемая операция async), я хочу запустить действие delete (более похоже на побочный эффект внутри побочного эффекта). Когда я запускаю действие NewMessagesReceivedAction (сообщения), данные должны быть из этого.threadsService.loadNewMessagesForUser (uiState.userId). Надеюсь, это немного изменит ситуацию.
Hi @John Hamm. Спасибо за ответ. Я обновил свой вопрос, чтобы прояснить ситуацию. Надеюсь, что это поможет. Идеальная ситуация: мне НЕ нужно передавать сообщения в this.threadsService.deleteMessagesQueuePerUser, поэтому я могу упростить эту функцию как this.threadsService.deleteMessagesQueuePerUser (userId). Я просто не знаю, как получить NewMessage от наблюдаемого ПЕРЕД. Кроме того, ваше решение, я получаю userId? Вы отображаете только сообщения, откуда приходит userId, поскольку он принадлежит коммутатору. –
Ваше решение, есть ошибка машинописного текста: аргумент типа 'Message []' не присваивается параметру типа 'Observable'. Это ошибка подсветки сообщений в this.threadsService.deleteMessagesQueuePerUser (messages, userId) –
Вы получаете userId из содержащего switchMap. Вы заметите, что внутренний «.map (messages ...» будет иметь доступ к любым переменным, переданным на любые внешние карты или наблюдаемые. Вместо того, чтобы заканчивать switchMap после загрузкиNewMessagesForUser, я просто перекодирую другую карту на первую карту, а не заканчивая switchMap, чтобы он мог получить доступ к userId. –