Reputation: 1023
Currently, I am calling the database to extract all the conversations of a specific user. After that, I am looping through those conversations and I extract metadata such as message text, message sender and etc from each conversation.
I create an object for each with its' metadata which then are all stored in an Array - in my case this.recentChats
.
this.af.getObservable(`userChats/${this.userID}/`).pipe(
// we map the array of conversations to an array of the (before inner) observables
map(recentConversations =>
recentConversations.map(conversation =>
this.af.getObservableSortByVar(`allChats/${conversation.conversationID}/`, 'lastUpdate'))),
// combine the observables. will emit a new value of ALL conversation data when one of the conversations changes
switchMap(recentConversations => combineLatest(recentConversations)),
// map each conversation to the conversation object
map(conversations =>
conversations.map(conversationData => {
let userKey, lastMessage, lastMessageText, lastMessageSender, lastMessageDate;
for (let i = 0; conversationData.length > i; i++) {
switch (conversationData[i].key) {
case 'messages': {
lastMessage = (conversationData[i][Object.keys(conversationData[i])[Object.keys(conversationData[i]).length - 1]]);
lastMessageText = lastMessage.message;
lastMessageSender = lastMessage.sender;
lastMessageDate = lastMessage.date;
}
case 'users': {
userKey = conversationData[i].userKey;
}
}
}
return this.createConversationObject('username', userKey, lastMessageSender, lastMessageText, lastMessageDate);
}))
).subscribe(recentChats => this.recentChats = recentChats);
However, on the line where return this.createConversationObject('username', ...)
is called, I have been struggling to assign a user's actual username, fetched from the database.
Basically, I am using the userKey
local variable, which is obtained from the switch-case code above, in order to attempt to do the following:
let tempUsername;
this.af.getUserName(userKey).then((username) => {
tempUsername = username;
}
And then pass the tempUsername
in the return statement. However, I have been struggling with making the result would to be awaited - in order for the username to be fetched, before the return is called.
Does anyone have any suggestions how can I properly achieve the desired result?
Upvotes: 3
Views: 464
Reputation: 3165
Edit (after understanding the issue more closely)
Here's the code example for the proposed solution: Code example
Here are the modification that needs to be done to your code:
In the map(conversations =>
block, return the modified object with userkey
appended and not the results of this.createConversationObject()
introduce switchMap
after this and convert the Promise to Observable using rxjs -> from
operator, also convert the results of the updated object returned from the previous map
operation into a new Observable using rxjs -> of
operators
now return the result of CombineLatest(OriginalObservable, fromPromiseObservable)
lastly you further need to map the results of these two Observable returns into one of use it directly in your call to this.createConversationObject()
and finally you can subscribe to the result to get the actual result as a final step
Hope this clarifies!
Original response
Here's my suggestion:
this.af.getUserName(userKey)
promise to an observable first by using fromPromise
provided by rxjs.CombineLatest
in the SwitchMap
block map
block to fetch the username for your return statementUpvotes: 1