Angular 在调用操作之前,将ngrx/effects中的RXJS操作链接到不同操作的Firebase的策略
我有一个我不知道如何处理的情况。情况是长时间拉Firebase,将一些可观察的数据返回ngrx/effects,然后再次调用Firebase删除一些数据,最后将第一个Firebase返回数据传递给一个Action,以便reducer执行其操作 这是ngrx/效果代码Angular 在调用操作之前,将ngrx/effects中的RXJS操作链接到不同操作的Firebase的策略,angular,firebase,firebase-realtime-database,rxjs,observable,Angular,Firebase,Firebase Realtime Database,Rxjs,Observable,我有一个我不知道如何处理的情况。情况是长时间拉Firebase,将一些可观察的数据返回ngrx/effects,然后再次调用Firebase删除一些数据,最后将第一个Firebase返回数据传递给一个Action,以便reducer执行其操作 这是ngrx/效果代码 constructor(private threadsService: ThreadsService, private store: Store<ApplicationState>) { }
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))
将在WebStorm中引发错误-类型“{}”上不存在属性“userId”。)
错误2:这三行行不通:
// .withLatestFrom(this.store.select("uiState"))
// .do(console.log)
// .switchMap(([messages, uiState]) => this.threadsService.deleteMessagesQueuePerUser(messages, uiState.userId))
这三行的想法是继续传递可观察到的消息,但我还需要uiState.userId来删除Firebase中的一些数据,方法是:this.threadsService.deleteMessagesQueuePerUser(messages,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));
}
firebaseUpdate(数据保存){
常量主题=新主题();
this.sdkDb.update(dataToSave)
.那么(
val=>{
主题。下一个(val);
subject.complete();
},
错误=>{
主体错误(err);
subject.complete();
}
);
返回subject.asObservable();
}
LoadNewMessagesFruser(uid:string):可观察{
log(“我们正在拉服务器!uid:+uid”);
返回此.findMessageFormMessageKeys(此.findMessageKeysPreUserUnread(uid));
}
FindMessageFormMessageKeys(messageKeys$:可观察):可观察{
返回消息键$
.map(pspp=>pspp.map(messageKey=>this.db.object('message/'+messageKey)))
.flatMap(fbojs=>Observable.CombineTest(fbojs))
}
deleteMessagesQueuePerUser(消息:可观察,uid:string):可观察{
让dataToSave={};
dataToSave['messagesqueperuser/'+uid]=null;
此.firebaseUpdate(dataToSave);
返回消息;
}
findMessageKeysPreUserUnread(uid:string):可观察{
返回此.db.list('messagesqueperuser/'+uid)
.map(getKeys=>getKeys.map(p=>p.key));
}
有谁能给我指出正确的方向,让我知道如何正确地构建和编写这篇文章
更新以澄清。
是的,我有UiState类型。我真正想要的是从这个.threadsService.loadNewMessagesForUser(uiState.userId)获取新消息。在我获得新消息之后(因为这是一个可观察的异步操作),我想运行delete操作(更像是副作用中的副作用)。当我触发操作NewMessagesReceivedAction(messages)时,数据应该来自这个.threadsService.loadNewMessagesForUser(uiState.userId)。希望这能澄清一点。我假设您有一个UiState类型 这是一种方法:
@Effect() newMessages$ = Observable.interval(5000)
.withLatestFrom(this.store.select("uiState"))
.map(([any,uiState]) => uiState)
.filter(uiState => uiState.userId)
.switchMap(uiState => threadsService.loadNewMessagesForUser(uiState.userId)
.switchMap(newMessages => threadsService.deleteMessagesQueuePerUser(newMessages, uiState.userId)
.map(deletedMessages => newMessages)))
.map(messages => ({ type:'MESSAGES_RECEIVED', payload: messages }));
工作冲击器:
你好,约翰·哈姆。谢谢你的回答。我更新了我的问题以澄清问题。希望这能有所帮助。理想的情况是我不需要将消息传递到this.threadsService.deleteMessagesQueuePerUser,因此我可以将函数简化为this.threadsService.deleteMessageSquePeruser(userId)。我只是不知道如何从一个可观察的物体上得到新的信息。还有,您的解决方案,我是否获得用户ID?您只映射用户ID来自的消息,因为它属于switchMap。您的解决方案存在typescript错误:“Message[]”类型的参数不能分配给“Observable”类型的参数。在此.threadsService.deleteMessagesQueuePerUser(messages,userId)中的消息上突出显示错误,您可以从包含的开关映射中获取userId。您将注意到内部“.map(消息…”将有权访问传递给任何外部映射或可观察对象的任何变量。在加载NewMessagesForser后,我没有结束switchMap,而是将另一个映射链接到第一个映射,而不是结束switchMap,这样它就可以访问用户ID。但您的代码仍然无法像我前面提到的那样工作。Webstorm说的参数类型为“Message[]'不可分配给'Observable'类型的参数。我认为在switchMap中,您的代码会将消息转换为非可观察的。因此它不会传递给下一个deleteMessagesQueuePerUser函数,该函数需要可观察的并返回可观察的。正如我在更新中提到的,我只需要“方面”函数deleteMessagesQueuePerUser使用用户ID在Firebase中删除某人。我需要的消息仍然来自loadNewMessagesForUser(用户ID)。谢谢!很抱歉,我使用vscode作为编辑器。我这里有一个正在工作的plunker,您可以看到它正在工作。我还更新了我的答案:
@Effect() newMessages$ = Observable.interval(5000)
.withLatestFrom(this.store.select("uiState"))
.map(([any,uiState]) => uiState)
.filter(uiState => uiState.userId)
.switchMap(uiState => threadsService.loadNewMessagesForUser(uiState.userId)
.switchMap(newMessages => threadsService.deleteMessagesQueuePerUser(newMessages, uiState.userId)
.map(deletedMessages => newMessages)))
.map(messages => ({ type:'MESSAGES_RECEIVED', payload: messages }));