Send, receive, and fetch threaded messages using the CometChat JavaScript SDK. Includes real-time listeners, thread message history, and filtering thread replies.
Quick Reference for AI Agents & Developers
Report incorrect code
Copy
Ask AI
// Send message in a threadconst msg = new CometChat.TextMessage("UID", "Reply", CometChat.RECEIVER_TYPE.USER);msg.setParentMessageId(100);await CometChat.sendMessage(msg);// Fetch thread messagesconst request = new CometChat.MessagesRequestBuilder() .setParentMessageId(100).setLimit(30).build();const messages = await request.fetchPrevious();// Exclude thread replies from main conversationconst request = new CometChat.MessagesRequestBuilder() .setUID("UID").setLimit(30).hideReplies(true).build();
Messages that are started from a particular message are called Threaded messages or simply threads. Each Thread is attached to a message which is the Parent message for that thread.
As mentioned in the Send a Message section. You can either send a message to a User or a Group based on the receiverType and the UID/GUID specified for the message. A message can belong to either of the below types:
Text Message
Media Message
Custom Message.
Any of the above messages can be sent in a thread. As mentioned, a thread is identified based on the Parent message. So while sending a message the parentMessageId must be set for the message to indicate that the message to be sent needs to be a part of the thread with the specified parentMessageId.This can be achieved using the setParentMessageId() method provided by the object of the TextMessage, MediaMessage and CustomMessage class. The id specified in the setParentMessageId() method maps the message sent to the particular thread.Example to Send a Text Message in a thread in a user conversation.
User
TypeScript
Report incorrect code
Copy
Ask AI
let textMessage = new CometChat.TextMessage(UID, "Hello", CometChat.RECEIVER_TYPE.USER);textMessage.setParentMessageId(100);CometChat.sendMessage(textMessage).then( message => { console.log('Message sent successfully', message); }, err => { console.log('err', err); })
Report incorrect code
Copy
Ask AI
let receiverId = "UID", receiverType: string = CometChat.RECEIVER_TYPE.USER, textMessage: CometChat.TextMessage = new CometChat.TextMessage(receiverId, "Hello", receiverType), messageId: number = 100;textMessage.setParentMessageId(messageId);CometChat.sendMessage(textMessage).then( (message: CometChat.TextMessage) => { console.log('Message sent successfully', message); }, (error: CometChat.CometChatException) => { console.log('Message sending failed', error); });
The above snippet shows how a message with the text “Hello” can be sent in the thread with parentMessageId 100.Similarly, using the setParentMessageId() method, Media and Custom Messages can be sent in threads too.
The procedure to receive real-time messages is exactly the same as mentioned in the Receive Messages. This can be achieved using the MessageListener class provided by the SDK.
Always remove listeners when they’re no longer needed (e.g., on component unmount or page navigation). Failing to remove listeners can cause memory leaks and duplicate event handling.
To add a MessageListener, you can use the addMessageListener() method of the SDK. The only thing that needs to be checked is if the received message belongs to the active thread. This can be done using the parentMessageId field of the message object.
Message Listener
TypeScript
Report incorrect code
Copy
Ask AI
const listenerID = "UNIQUE_LISTENER_ID";const activeThreadId = 100;CometChat.addMessageListener(listenerID,new CometChat.MessageListener({ onTextMessageReceived: textMessage => { if(textMessage.getParentMessageId() == activeThreadId) { console.log("Text message received for active thread.", textMessage); } }, onMediaMessageReceived: mediaMessage => { if(mediaMessage.getParentMessageId() == activeThreadId) { console.log("Media message received for active thread.", mediaMessage); } }, onCustomMessageReceived: customMessage => { if(customMessage.getParentMessageId() == activeThreadId) { console.log("Custom message received for active thread.", customMessage); } }}));
Report incorrect code
Copy
Ask AI
const listenerID: string = "UNIQUE_LISTENER_ID";const activeThreadId: number = 100;CometChat.addMessageListener( listenerID, new CometChat.MessageListener({ onTextMessageReceived: (textMessage: CometChat.TextMessage) => { if (textMessage.getParentMessageId() == activeThreadId) { console.log("Text message received for active thread.", textMessage); } }, onMediaMessageReceived: (mediaMessage: CometChat.MediaMessage) => { if (mediaMessage.getParentMessageId() == activeThreadId) { console.log("Media message received for active thread.", mediaMessage); } }, onCustomMessageReceived: (customMessage: CometChat.CustomMessage) => { if (customMessage.getParentMessageId() == activeThreadId) { console.log("Custom message received for active thread.", customMessage); } } }));
You can fetch all the messages belonging to a particular thread by using the MessagesRequest class. In order to get an object of the MessagesRequest class, you need to use the MessagesRequestBuilder class. and use the setParentMessageId() method of the MessagesRequestBuilder to inform the SDK that you only need the messages belonging to the thread with the specified parentMessageId.Once you have the object of the MessagesRequest class, you need to call the fetchPrevious() method to get the latest messages in the thread. In one integration, a maximum of 100 messages can be fetched. If you wish to fetch the next set of messages, you need to call the fetchPrevious() method again on the same object.
Fetch all message for a thread
TypeScript
Report incorrect code
Copy
Ask AI
let limit = 30;let parentMessageId = 1;let messagesRequest = new CometChat.MessagesRequestBuilder() .setLimit(limit) .setParentMessageId(parentMessageId) .build();messagesRequest.fetchPrevious().then( messages => { console.log("Messages for thread fetched successfully", messages); }, error => { console.log("Message fetching failed with error:", error); });
Report incorrect code
Copy
Ask AI
let limit: number = 30, parentMessageId: number = 1, messagesRequest: CometChat.MessagesRequest = new CometChat.MessagesRequestBuilder() .setLimit(limit) .setParentMessageId(parentMessageId) .build();messagesRequest.fetchPrevious().then( (messages: CometChat.BaseMessage[]) => { console.log("Messages for thread fetched successfully", messages); }, (error: CometChat.CometChatException) => { console.log("Message fetching failed with error:", error); });
Avoid Threaded Messages in User/Group Conversations
While fetching messages for normal user/group conversations using the MessagesRequest, the threaded messages by default will be a part of the list of messages received. In order to exclude the threaded messages from the list of user/group messages, you need to use the hideReplies() method of the MessagesRequestBuilder class. This method takes a boolean argument which when set to true excludes the messages belonging to threads from the list of messages.
let UID: string = "UID", limit: number = 30, messagesRequest: CometChat.MessagesRequest = new CometChat.MessagesRequestBuilder() .setUID(UID) .setLimit(limit) .hideReplies(true) .build();messagesRequest.fetchPrevious().then( (messages: CometChat.BaseMessage[]) => { console.log("Messages fetched successfully", messages); }, (error: CometChat.CometChatException) => { console.log("Message fetching failed with error:", error); });
Report incorrect code
Copy
Ask AI
let GUID: string = "GUID", limit: number = 30, messagesRequest: CometChat.MessagesRequest = new CometChat.MessagesRequestBuilder() .setGUID(GUID) .setLimit(limit) .hideReplies(true) .build();messagesRequest.fetchPrevious().then( (messages: CometChat.BaseMessage[]) => { console.log("Messages fetched successfully", messages); }, (error: CometChat.CometChatException) => { console.log("Message fetching failed with error:", error); });
The above snippet will return messages between the logged in user and cometchat-uid-1 excluding all the threaded messages belonging to the same conversation.
Best Practices
Track active thread ID: Store the current thread’s parentMessageId to filter incoming messages
Use hideReplies(true): Exclude thread replies from main conversation to avoid clutter
Paginate thread messages: Use setLimit() and fetchPrevious() for large threads
Remove listeners on thread close: Clean up message listeners when user exits a thread view
Show reply count: Display the number of replies on parent messages to indicate thread activity
Troubleshooting
Issue
Cause
Solution
Thread replies in main chat
hideReplies not set
Add .hideReplies(true) to MessagesRequestBuilder
Missing thread messages
Wrong parent ID
Verify setParentMessageId() uses correct message ID
Real-time messages not filtered
Not checking parent ID
Compare getParentMessageId() with active thread ID