Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating custom components inside a callback does not work correctly #5634

Open
3 of 5 tasks
aghasemi opened this issue Nov 1, 2022 · 7 comments
Open
3 of 5 tasks
Labels
feature:callbacks feature:custom-components type:enhancement Requests for feature enhancements or new features

Comments

@aghasemi
Copy link

aghasemi commented Nov 1, 2022

Checklist

  • I have searched the existing issues for similar issues.
  • I added a very descriptive title to this issue.
  • I have provided sufficient information below to help reproduce this issue.

Summary

Hi,

Is it possible to create a custom component inside a callback? I see some weird behaviour with my streamlit_js_eval component which happens only when using callbacks. Can you help please or confirm it doesn't work at all?

Reproducible Code Example

import streamlit as st, time

from streamlit_js_eval import streamlit_js_eval





def disp_width():
    width = streamlit_js_eval(js_expressions='screen.width', want_output = True, key = 'SCR')
    to_display = f"Screen width is _{width}_"

    st.write(to_display)





st.button("Display Screen Width", on_click=disp_width)

Steps To Reproduce

  1. Run the code example

Expected Behavior

A line of text is written.

Current Behavior

A line of text is written but then immediately removed.

Is this a regression?

  • Yes, this used to work in a previous version.

Debug info

  • Streamlit version:
  • Python version:
  • Operating System:
  • Browser:
  • Virtual environment:

Additional Information

No response

Are you willing to submit a PR?

  • Yes, I am willing to submit a PR!

Community voting on feature requests enables the Streamlit team to understand which features are most important to our users.

If you'd like the Streamlit team to prioritize this feature request, please use the 👍 (thumbs up emoji) reaction in response to the initial post.

@aghasemi aghasemi added type:bug Something isn't working status:needs-triage Has not been triaged by the Streamlit team labels Nov 1, 2022
@willhuang1997 willhuang1997 added feature:custom-components feature:callbacks and removed type:bug Something isn't working status:needs-triage Has not been triaged by the Streamlit team labels Nov 1, 2022
@willhuang1997
Copy link
Collaborator

willhuang1997 commented Nov 1, 2022

Hi @aghasemi , this seems to be related to #3977. Let me know if you think I'm wrong!

@carolinedlu carolinedlu added type:enhancement Requests for feature enhancements or new features added-voting-callout labels Nov 8, 2022
@coolkau
Copy link

coolkau commented Nov 14, 2022

The current behaviour
A line of text is written but then immediately removed.

is pretty much how I would expect the callbacks to work. To my best knowledge the callback is executed before the run. So when the callback triggers the line is added to the screen. Then the entire script is re-run. Then of course the line is gone, given the piece of code with the extra line is never executed during the re-run.

So really the way to do this is to have a placeholder string outside of the callback, which will be filled in the callback.

st.write("", key="key")
def disp_width():
    width = streamlit_js_eval(js_expressions='screen.width', want_output = True, key = 'SCR')
    to_display = f"Screen width is _{width}_"
   st.session_state["key"] = to_display
    

@aghasemi
Copy link
Author

Hello again. Here is a similar and likely related issue: aghasemi/streamlit_js_eval#2

I'm not much informed about the internals of Streamlit, so cannot dig very deep...

@coolkau
Copy link

coolkau commented Feb 26, 2023

I still dont think it is a bug, but exactly how a callback should work.
@aghasemi have you tried putting your st.write(to_display) outside of the callback?

@coolkau
Copy link

coolkau commented Feb 26, 2023

If you watch this https://docs.streamlit.io/library/advanced-features/session-state
There are two steps: first the callback is executed, then the script is re-run. However, they are distinct tasks. The callback execution is not part of the actual script run.

So any widget you place within the callback will be visible for a brief second, while the callback is executed. Then, when the main run happens it will be removed again, as it is not part of the re-run. The callbacks pretty much just exist to to update the session state before the script is executed.

I hope this helps.

@aghasemi
Copy link
Author

Hello,

Sorry for being late. The problem is that this issue actually happens when you call SJE inside any branch, e.g. an if or a loop, not just callbacks. Any idea why this happens?

@aghasemi
Copy link
Author

aghasemi commented Mar 6, 2024

Hello,

Sorry for being late. The problem is that this issue actually happens when you call SJE inside any branch, e.g. an if or a loop, not just callbacks. Any idea why this happens?

Hi. This may be of interest: aghasemi/streamlit_js_eval#2

See the last message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature:callbacks feature:custom-components type:enhancement Requests for feature enhancements or new features
Projects
None yet
Development

No branches or pull requests

4 participants