Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@raethlein
Copy link
Collaborator

@raethlein raethlein commented Dec 13, 2024

Describe your changes

An observed user behavior in Streamlit is to change some widget's input and then directly click on a button to submit the change and see the result in the web app.
When not losing the focus on the input field first, this can sometimes lead to the trigger rerun message being sent to the server before the input's change rerun update. If the trigger button's action accesses the other widget's state, the state is read before the input's change data is processed and the update is only visible upon the next rerun as reported in #10007.

This PR wraps the setTriggerValue functions in a setTimeout(setTriggerValueLogic, 0) call. When the input's value change is in JS' event loop, e.g. via an onBlur event, and the trigger value is on the event loop, e.g. via a button's onClick event, this wrapper will put the trigger value at the end of the current event loop (without any measurable delay due to timeout 0). This assumes that we usually want to process other rerun data first and the trigger value as a follow-up action of that information. Even if this assumption is not true, right now without the PR the order is random and with this we put some more deterministic behavior around the messages which should not make any situation worse.

Note that the e2e test would also fail if we use the normal execution flow and not a callback on the button. Also, the e2e test is able to trigger the bug always, whereas manually I was only able to trigger it when loading the page in Chrome's mobile device emulator as reported by the user in
#10007. My assumption is that playwright and the mobile touch on the button are fast enough to schedule the event, whereas a mouse click loses focus on the text area first before triggering the click which puts the text area's onBlur event in front of the trigger event in JS' event loop.
I believe this behavior changed in recent versions where we refactored the components to functional ones using some custom hooks to sync the new value internally and committing to the server. My assumption is that this increased the likelihood of events being scheduled later in the event loop.

GitHub Issue Link (if applicable)

Closes #10007

Testing Plan


Contribution License Agreement

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.

@raethlein raethlein added security-assessment-completed Security assessment has been completed for PR impact:users PR changes affect end users type:enhancement Requests for feature enhancements or new features change:bugfix PR contains bug fix implementation and removed type:enhancement Requests for feature enhancements or new features labels Dec 13, 2024
@sfc-gh-braethlein sfc-gh-braethlein changed the title Schedule trigger events in the end of the event loop Schedule trigger events at the end of the event loop Dec 13, 2024
@raethlein raethlein force-pushed the fix/issue-10007 branch 2 times, most recently from 2bfae04 to 865fc55 Compare December 13, 2024 11:14
* the setTimeout is used to ensure the input field value is sent to the server before the button click
* by putting the the button click in the end of the event loop
*
* Returns a promise that is resolved as soon as the timeout was triggered for testing purposes.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand this part -- is it referring to the 0 timeout that will ensure we don't wait to add this to the task queue, or something else?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you referring to the entire JS doc or the last part about the promise return? I have updates the doc string slightly, perhaps its clearer now?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the rewording is clearer to me, thanks! Added a nit on the english.

@sfc-gh-lwilby
Copy link
Collaborator

LGTM I just found some of the description and comments a bit hard to follow and suggested some changes that I think would be clearer.

@raethlein raethlein merged commit d25aef3 into develop Dec 14, 2024
29 checks passed
sfc-gh-lwilby added a commit that referenced this pull request Dec 16, 2024
This is a small change to the setTriggerValueAtEndOfEventLoop docstring
based on discussion [in this
PR](#10018 (comment)).

## Describe your changes

## GitHub Issue Link (if applicable)

## Testing Plan

Docstring only, no tests needed. 

---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this
project are made under the Apache 2.0 license.
edegp pushed a commit to edegp/streamlit that referenced this pull request Jan 19, 2025
## Describe your changes

Put trigger-caused actions at the end of the event loop to let other events that change & sync input data come first if they happen at the same time.

## GitHub Issue Link (if applicable)

Closes streamlit#10007

## Testing Plan

- Updated existing unit tests because with the timeout they started to
fail
- Added an e2e test with the logic reported in streamlit#10007. The test fails
without the `setTimeout` as it mimics exactly what the user reported.

---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this
project are made under the Apache 2.0 license.
edegp pushed a commit to edegp/streamlit that referenced this pull request Jan 19, 2025
This is a small change to the setTriggerValueAtEndOfEventLoop docstring
based on discussion [in this
PR](streamlit#10018 (comment)).

## Describe your changes

## GitHub Issue Link (if applicable)

## Testing Plan

Docstring only, no tests needed. 

---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this
project are made under the Apache 2.0 license.
@lukasmasuch lukasmasuch deleted the fix/issue-10007 branch March 13, 2025 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:bugfix PR contains bug fix implementation impact:users PR changes affect end users security-assessment-completed Security assessment has been completed for PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Text area widget value not updated in session state when directly followed by button tap

5 participants