Comment Thread : onSubmit misses last comment

I am trying to send email on each comment on a comment thread.

const comments = commentThread1.data;
console.log(comments, comments.length)
console.log(JSON.stringify(comments, null, 2))

this seems like always missing the last comment. for example if there is 3 message, log will show only 2, but when I hover over the data after the execution I see 3 data.

Is there a way to get all of these data on submit?

Thanks

1 Like

anyone ?

Can you post any reference screenshots?

Hi @mpmohi ,

I tested the following JavaScript query in my app, and it works perfectly for sending an email for each comment in commentThread1.data. It also includes the current time for each comment and handles errors robustly.

Here’s the updated code

setTimeout(() => {
  const comments = commentThread1.data || [];
  if (commentThread1.value) {
    comments.push({
      text: commentThread1.value,
      user: { name: current_user.fullName || current_user.email || 'Unknown User' },
      created_at: new Date().getTime()
    });
  }

  if (!comments.length) return;

  comments.forEach((comment, index) => {
    sendEmailQuery.trigger({
      additionalScope: {
        commentText: comment.text || comment.value || 'No comment text',
        user: comment.user?.name || comment.user?.email || 'Unknown User',
        timestamp: comment.created_at ? new Date(comment.created_at).toISOString() : new Date().toISOString(),
        commentIndex: index + 1
      }
    });
  });
}, 100);


Trigger: sendEmailQuery



Screenshots of Result:



This solution is working well on my end. If you'd like to refine it further, I'm happy to assist. I can also set up a quick demo in my app to walk you through the process step by step.

Please don’t hesitate to reach out if this meets your needs or if there’s anything you'd like to improve. I'm here to help!

Could this be an indexing issue in the code?

Comments are stored in an array indexed [0, 1, 2]
With the latest stored in index 0 (newest to oldest).

Email sending code iterates through indexes 1-3 considering there are 3 comments in this example.
But misses the latest comment because it sits in index 0 but the code starts looping from 1..?

Hello thanks for your detailed post, you see in your code you are appending

  const comments = commentThread1.data || [];
console.log("Length of Comments in test: ", comments.length)

  if (commentThread1.value) {
    comments.push({
      text: commentThread1.value,
      user: { name: current_user.fullName || current_user.email || 'Unknown User' },
      created_at: new Date().getTime()
    });
  }
console.log("Length of Comments in test after : ", comments.length)

My concern was why do we need to manually push this ? also you will see the length difference before and after pushing

hi,
no this is because of my previous comment

  const comments = commentThread1.data || [];
console.log("Length of Comments in test: ", comments.length)

  if (commentThread1.value) {
    comments.push({
      text: commentThread1.value,
      user: { name: current_user.fullName || current_user.email || 'Unknown User' },
      created_at: new Date().getTime()
    });
  }
console.log("Length of Comments in test after : ", comments.length)

hi @mpmohi

Due to Retool's asynchronous state updates, commentThread1.data may not include the latest comment at the time the "Submit" event fires. To ensure the new comment is included in actions like email notifications, we manually append commentThread1.newCommentValue to the comments array.

This explains the observed difference in array length before and after the manual push.

To ensure all comments are processed, including the latest one, we introduce a 500ms setTimeout to allow Retool time to update commentThread1.data:

setTimeout(() => {
  const comments = commentThread1.data || [];
  if (!comments.length) return;

  comments.forEach((comment, index) => {
    sendEmailQuery.trigger({
      additionalScope: {
        commentText: comment.text || comment.value || 'No comment text',
        user: comment.user?.name || comment.user?.email || 'Unknown User',
        timestamp: comment.created_at ? new Date(comment.created_at).toISOString() : new Date().toISOString(),
        commentIndex: index + 1,
      },
    });
  });
}, 500);

Alternative (Database Approach)

Store comments in a Retool Database table (e.g., comments) with thread_id, text, user, and created_at. On submit, insert the new comment, fetch all related comments, and send emails based on the database, avoiding timing issues entirely.

1 Like