i am currently in the process of modifying a basic SignalR Chat feature.
Here is the situation: when a user sends a message, the message gets sent successfully. However, the textarea from which it was sent remains filled with empty space (aside from the placeholder). This space consists of about 13 white spaces stored in event.currentTarget.defaultValue. I have attempted to resolve this by setting it to null or '', but the whitespace persists and obscures the placeholder.
The original input field is a string, but in my version, I have converted it into a BehaviorSubject. Additionally, I have added an observable of that BehaviorSubject.
txtMessage: string = null;
txtSubject: BehaviorSubject<string>;
txtStatus: Observable<string>;
this.txtSubject = new BehaviorSubject<string>(this.txtMessage);
this.txtStatus = this.txtSubject.asObservable();
this.txtStatus.subscribe(status => {
if(status !== null && status.length)
let senderid = this.userid;
let receiverid = this.selectedChatFriend.id;
let message = 'typing:' + senderid + ';receiver' + receiverid;
this.chatService.startedTyping(message);
}
if(status == null && this._selectedChatFriend !== null && this._selectedChatFriend !== undefined){
let senderid = this.userid;
let receiverid = this.selectedChatFriend.id;
let message = 'nottyping:' + senderid + ';receiver' + receiverid;
this.chatService.stoppedTyping(message);
}
});
Issue at hand: After a user sends a message, the recipient is notified. Initially, everything works smoothly on the first message. However, subsequent messages show the whitespace instead of resetting to an empty textarea with a null value. As a result, the isTyping event is not triggered when the user starts typing again due to the if statement in 'starttyping' not anticipating whitespace.
textinputreceived(event: any){
if (event.currentTarget.value.length > 0 && event.inputType == "insertLineBreak"){
//event.preventDefault();
this.sendTextMessage(event.currentTarget.value);
}
//filter out anything that is not the txtMessage
if(event.currentTarget.value.length == 1 && event.inputType == "insertText"){
//user started typing
//triggers the isTyping
this.txtSubject.next(event.data);
} else if (event.currentTarget.value == '' && event.inputType == "deleteContentBackward"){
//user just deleted the only char in the message
//triggers stopped typing
this.txtSubject.next(null);
}
}
The HTML:
<div class="type_msg">
<div class="input_msg_write">
<textarea type="text"
id="chatbx"
placeholder="Type a message"
class="write_msg"
[value]="txtMessage"
(input)="textinputreceived($event)"
(keydown.enter)="sendTextMessage($event)">
</textarea>
<button class="msg_send_btn"
type="button"
(click)="sendTextMessage($event)">
<i class="fa fa-paper-plane-o" aria-hidden="true"gt;
<mat-icon style="color:black;margin-top:10px; font-size: 42px; margin-left: -45px;">send</mat-icon>
</i>
</button>
</div>
</div>
and the method to send messages:
sendTextMessage(event: any): void {
this.message = new ChatMessage();
if (this.selectedChatFriend) {
this.message.messageReceiverId = this.selectedChatFriend.id;
}
this.message.message = event.currentTarget.value;
this.txtSubject.next(null);
event.currentTarget.value = null;
this.txtMessage = null;
this.message.messageSenderId = this.userid;
this.message.type = "sent";
this.message.timeStamp = new Date();
if(this.message.messageReceiverId && this.message.message.length > 0){
debugger; //hier pauze is al genoeg om te werken :o
}
this.chatService.sendMessage(this.message);
}
There are a few peculiar occurrences:
A. It takes only one backspace press to delete the whitespace (13 characters), reveal the placeholder, and trigger the isTyping event. I tried simulating a JQueryEvent keypress for backspace without success.
B. When I debug the sendmessage function line by line in the browser's debug mode, everything functions as intended. However, under normal conditions, some issues arise. I experimented with delays and code reorganization but did not achieve the desired outcome.
C. In my chat.html file, where users input their messages, I have two methods specified: (input)="textinputreceived($event)" and (keydown.enter)="sendTextMessage($event)". If I remove the latter, the condition "event.currentTarget.value.length > 0 && event.inputType == "insertLineBreak"" does not activate upon the first Enter key press—only after pressing backspace, does it become active (likely due to the initial whitespace defaultValue). Yet, removing this leads to other complications.
I am still grasping TypeScript concepts and may be overlooking something fundamental (I read about thread-related issues). If you have any suggestions on how to tackle this challenge, I would appreciate your insights!
Additional attempts I made:
- Manipulated the value bindings using [] and [()];
- Attempted changing the textarea to a div, but no success;
Update: After delving deeper and condensing everything into a single line, I managed to reduce the whitespaces to only one character. I also tried manipulating the DOM to eliminate it, but so far, no luck. The strangest part is that this solution works fine when I debug step by step...