Reputation: 186
I am currently migrating from rxjs 5 to 6, and I cannot figure out how to access an argument from a previous Observable. I was using the following code in rxjs 5:
return this.userProvider.getCurrentUser().concatMap(currentUser => {
return this.db.collection('chats').doc(room).collection<MessageModel>('messages', ref => ref.limit(25).orderBy("date", "desc")).stateChanges(["added"])
.map(docChange => docChange.map(doc => {
const message = doc.payload.doc.data() as MessageModel;
message.sender = (message.senderId === currentUser.userId) ? currentUser : receiver;
return message;
}).reverse());
});
I have converted the code to rxjs 6 (using pipe
) as follows:
return this.userProvider.getCurrentUser().pipe(
concatMap(currentUser => {
return this.db.collection('chats').doc(room)
.collection<MessageModel>('messages', ref => ref.limit(25).orderBy('date', 'desc')).stateChanges(['added']);
}),
map(docChange => docChange.map(doc => {
const message = doc.payload.doc.data() as MessageModel;
message.sender = (message.senderId === currentUser.userId) ? currentUser : receiver;
return message;
}).reverse())
);
In this way, however, I cannot access currentUser, since it is only accessible in the scope of concatMap. How would I be able to refactor the code in order to access currentUser
? Thank you.
Upvotes: 1
Views: 1329
Reputation: 17762
It seems that in your original RxJs 5.x code you were applying the logic .map(docChange => ....
to the result of this.db.collection('chats').doc(room).collection<MessageModel>(....)
, result which likely to be an Observable which emits an Array-like of MessageModel
(s,
If all this is true, then you may consider an approach which is close to your RxJs code along the following lines
return this.userProvider.getCurrentUser().pipe(
concatMap(currentUser =>
this.db.collection('chats').doc(room).collection<MessageModel>('messages', ref => ref.limit(25).orderBy('date', 'desc')).stateChanges(['added'])
.pipe(
map(
docChange => docChange.map(doc => {
const message = doc.payload.doc.data() as MessageModel;
message.sender = (message.senderId === currentUser.userId) ? currentUser : receiver;
return message;
}).reverse()
)
)
)
);
Here we pipe the map
operator directly into the result of the db.collection
query, so that we have immediately in scope the currentUser
.
I am not able to reproduce the case, so this is a bit of speculation and the approach has to be validated. I hope anyways you grasp the idea behind it.
Upvotes: 0
Reputation: 11345
You can pass current user along with another pipe
and map
return this.userProvider.getCurrentUser().pipe(
concatMap(currentUser =>
this.db.collection('chats').doc(room)
.collection<MessageModel>('messages', ref => ref.limit(25).orderBy('date', 'desc')).stateChanges(['added'])
.pipe(map(docChange)=>({currentUser,docChange}))
),
map(({currentUser,docChange}) => docChange.map(doc => {
const message = doc.payload.doc.data() as MessageModel;
message.sender = (message.senderId === currentUser.userId) ? currentUser : receiver;
return message;
}).reverse())
);
Upvotes: 3