So, I have this chat bot where you could ask a question and the bot will analyze the question and reply to it accordingly. So, the user just needs to input text in the input bar the question he/she wants to ask, and when he/she clicks submit button or just hit enter, the question is pushed to the conversation array and the bot replies based on the question asked and also the reply of the bot is also added to the conversation array. then the conversation array is mapped so that all conversations are rendered in the chat page in a way similar to facebook messenger; the chat bot’s reply are in the left side of the chat page and the question a user asks are on the right side of the chat page.(this is done when mapping the conversation array, all chats on the odd index are questions asked by the user, and the conversation on the even index is that of the bot’s reply). However, the problem I am facing now is, if the user inputs text and submits it very fast and repeatedly, the order of the conversation array gets messed up(for example, if I input and hit submit/enter four times at a very fast speed, all my 4 conversations I typed are rendered as if it’s a conversation between me and the bot and once the bot has a reply for the first question I asked, it’s displayed after 4 consecutive texts of mine and it might be even displayed either on the right side of the chat page or the left side. How can I solve this problem in react web app? I tried using setTimeout, but it’s not working for me or I am using it not in a correct way?
here is few of the code:
const SendChat = (e) => {
e.preventDefault();
// add text to show on conversation
dispatch(pushToChatConvArray({ user_conv: UserConversation }));
// Send API Call
// setTimeout(() => dispatch(botConvrse({ id: parseInt(sessionId), utt_user: userUtter })), 5000);
dispatch(botConvrse({ id: parseInt(sessionId), user_conv: UserConversation }));
setUserConversation("");
};
<div>
<form onSubmit={SendChat}>
<input
autoFocus
className="user-chat-form"
placeholder="What's on your mind?"
onChange={(e) => setUserConversation(e.target.value)}
value={UserConversation}
></input>
<IconButton type="submit">
<SendIcon />
</IconButton>
</form>
</div>
// the this content is displayed on the chatpage
let content = chatList.map((item, idx) =>
idx % 2 == 0 ? (
<motion.div
key={`chat ${idx}`}
>
<ChatContainer userOrBot={idx % 2 === 0 ? 0 : 1} conversation={item} />
</motion.div>
) : (
<motion.div
key={`chat ${idx}`}
>
<ChatContainer userOrBot={idx % 2 === 0 ? 0 : 1} conversation={item} />
</motion.div>
)
I tried to explain the main problem and provided few of the base code for the problem
3
Answers
Assuming the conversation should be contextual (waiting and responding to what has been previously messaged), one way would be to disable the form when the chatbot is thinking.
You can then set
botThinking
usinguseState
before and after using your yourbotConverse
method.You might also want to add something to your
sendChat
handler:Yes I saw what your problem is.
You probably have the chatList as react state.
And that is the array of text.
what about you update this state like
In this way, you can easily determine which is yours and bot’s.
It seems very unsafe to assume the conversation takes turns one-to-one like this.
My suggestion here would be to either block the input while a chat submission is being processed.
Example:
Or input which user is the owner of their part of the conversation. This part appears could be set as part of the dispatched actions when processed.
Example: