OvidijusParsiunas / deep-chat

Fully customizable AI chatbot component for your website
https://deepchat.dev
MIT License
1.26k stars 170 forks source link

DisplayLoadingBubble is not working for a given time interval #156

Closed MOHD-KAIF-hub closed 2 months ago

MOHD-KAIF-hub commented 2 months ago

Hi, I am utilizing deep-chat but when I am applying api call inside the useEffect getting DisplayLoadingBubble for a few milliseconds I am trying to show it until the API call is completed it should show can you please review my code I have been working on it last 2 days but didn't get any reliable solution. and I tried to use a mock API that is giving response after 3 seconds in this case also DisplayLoadingBubble is visible as same. here is my code please once tell me the mistake Thank you!

// import {DeepChat as DeepChatCore} from 'deep-chat'; <- type import { DeepChat } from 'deep-chat-react'; import React, { useState, useEffect, useRef } from 'react'; import './style.css';

export const App = () => { const chatElementRef = useRef(null); const [isLoading,setIsLoading]=useState(false);

const [initialMessages, setinitialMessages] = useState(); useEffect(() => { if (chatElementRef.current) { // Set initial messages first setinitialMessages([ { text: 'How are you doing?', role: 'loading' }, { html: `

`, role: 'user', }, ]) // Then set the request handler chatElementRef.current.request = { handler: async(body, signals) => { // setIsLoading(true); const bodyelement=document.getElementById('messages'); if(bodyelement) console.log(bodyelement); const chatbotId = '278efc0a-a1de-42a0-aa7d-ed06dc9f44f8'; const userQuery = body.messages[0].text; setinitialMessages((prev) => ([...prev, { text: userQuery, role: 'user' }])); try { // Make POST request with requestBody await fetch('http://34.224.93.99:5000/query-chatbot/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, // Set headers for POST body: JSON.stringify({ chatbotId, userQuery, source: 'Widget or Iframe', }) }) .then((response) => response.json()) .then((data) => { // Process response data signals.onResponse({ text: data.response }); setinitialMessages((prev) => ([...prev, { text: data.response, role: 'ai' }])); }) .catch((error) => { // Use error.message for better logging signals.onResponse({ error: error.message }); setinitialMessages((prev) => ([...prev, { text: error.message, role: 'error' }])); }); } catch (e) { signals.onResponse({ error: e.message }); // Use e.message for error logging setinitialMessages((prev) => ([...prev, { text: e.message, role: 'error' }])); }finally{ setIsLoading(false); } } }; } }, [chatElementRef]); // demo/style/textInput are examples of passing an object directly into a property // initialMessages is an example of passing a state object into a property return (

Deep Chat

); };
OvidijusParsiunas commented 2 months ago

Hi @MOHD-KAIF-hub.

I am not fully sure why you are attempting to manually toggle the displayLoadingBubble value. The Deep Chat component property values can't be dynamically changed (without the component being completely re-rendered), so when you assign a new value to displayLoadingBubble - the chat will only use the one given at the start. Hence the toggle does not do anything.

If the problem that you are referring to is the fact that the loading bubble is only displaying for a few milliseconds, the reason for that is upon changing the React State via setinitialMessages and setIsLoading - the component will be completely re-rendered. This is a basic React component convention. To see for yourself you can comment out the code that uses these setters and you will be able to observe the loading bubble working correctly. To store messages without having the component being re-renderd, I would instead suggest storing it by other means, such as an external variable. E.g. using the following syntax:

const initialMessages: MessageContent[] = [
  {text: 'How are you doing?', role: 'loading'},
  {
    html: `
      <div class="deep-chat-temporary-message">
        <button class="deep-chat-button deep-chat-suggestion-button" style="margin-top: 5px">give some bullet points?</button>
        <button class="deep-chat-button deep-chat-suggestion-button" style="margin-top: 6px">summarize it?</button>
        <button class="deep-chat-button deep-chat-suggestion-button" style="margin-top: 6px">What is this?</button>
      </div>`,
    role: 'user',
  },
];

export const App = () => {
...

And instead of setinitialMessages you can use initialMessages.push().

I would also suggest using the onNewMessage event to track message history, e.g:

onNewMessage={(newMessage) => {
  initialMessages.push(newMessage.message);
}}

Hopefully this helps you. Let me know if you have any questions. Thanks!

MOHD-KAIF-hub commented 2 months ago

First of all thanks for your response. I got what the mistake I was doing now I will handle thanks a lot.

OvidijusParsiunas commented 2 months ago

Hey, I will be closing this issue since the problem has been resolved. Thanks!