In my Ionic 5 / Angular app, I am displaying some items in an <ion-virtual-scroll>
below.
I am retrieving loadedMessages
from a ConversationsService which I am calling from my Typescript you can see below also:
<ion-virtual-scroll [items]="loadedMessages">
<ion-item-sliding *virtualItem="let message" #slidingItem>
<ion-item>
<ion-label>
<h2>{{ message.text}}</h2>
</ion-label>
</ion-item>
</ion-item-sliding>
</ion-virtual-scroll>
On the same page, I have the below form. When the user fills out this form, they add a new Message
to the Conversation
, they are able to do this using the conversation.id
.
<form [formGroup]="form">
<ion-item>
<ion-textarea formControlName="message"></ion-textarea>
</ion-item>
<ion-button (click)="onSendMessage()">Send</ion-button>
</form>
Here is my Typescript:
ngOnInit() {
this.route.paramMap.subscribe(paramMap => {
this.conversationsSub = this.conversationsService
.getConversation(paramMap.get('conversationId'))
.subscribe(conversation => {
this.conversation = conversation;
this.loadedMessages = this.conversation.messages;
this.mechanic = this.usersService.getUserByUserId(this.conversation.mechanicId);
this.form = new FormGroup({
message: new FormControl(null, {
updateOn: 'blur',
})
});
});
});
}
onSendMessage() {
this.conversationsService.addMessageToConversation(this.conversation.id, this.form.value.message);
}
As I mentioned, if I navigate to a different page, & then navigate back to Conversation-Detail
, the <ion-virtual-scroll>
shows the updated messages, but I want the scroll to update as soon as the user clicks the Send button, & the Message
is added.
And here is my ConversationsService:
export class ConversationsService {
private _conversations = new BehaviorSubject<Conversation[]>([
new Conversation(
'conversation1',
'user3',
'user1',
[
new Message('message1', 'Test message', 'user3', new Date(2018, 0O5, 0O5, 17, 23, 42, 11)),
new Message('message2', 'Another message', 'user1', new Date(2018, 0O6, 0O5, 17, 23, 42, 11))
]),
new Conversation(
'conversation2',
'user4',
'user2',
[
new Message('message3', 'my message', 'user4', new Date(2018, 0O7, 0O7, 17, 23, 42, 11)),
new Message('message4', 'more messages', 'user2', new Date(2018, 0O7, 0O7, 17, 23, 42, 11)),
])
]);
get conversations() {
return this._conversations.asObservable();
}
constructor(private authService: AuthService, private usersService: UsersService) { }
private createMessage(message: string): Message {
return {
id: Math.random().toString(),
text: message,
userId: this.authService.userId,
timestamp: new Date(Date.now())
};
}
getConversation(id: string) {
return this.conversations.pipe(
take(1),
map(conversations => {
return { ...conversations.find(conversation => conversation.id === id) };
}));
}
getConversationToAddMessage(id: string) {
return this._conversations.getValue().find(conversation => conversation.id === id);
}
addMessageToConversation(conversationId: string, message: string) {
this.getConversationToAddMessage(conversationId).messages.push(this.createMessage(message));
}
addConversation(mechanicId: string, message: string) {
const newConversation = new Conversation(
Math.random().toString(),
this.authService.userId,
mechanicId,
[this.createMessage(message)]
);
return this.conversations.pipe(
take(1),
delay(1000),
tap(conversations => {
this._conversations.next(conversations.concat(newConversation));
}));
}
}
Can someone please tell me how I can resolve this problem? I can provide further context if required also. Thanks a lot!