Streamlit-js-eval not executing javascript code

Hi all,

As per Force Reload of Webpage, I’m trying to refresh/reload my page calling the snippet after st.button(): streamlit_js_eval(js_expressions="parent.window.location.reload()"). However, it fails to do so and all of my previous my session_state + widget inputs still remain. I could’ve sworn this worked when I first tried it out, but I’m not sure if its because of the version of streamlit (v1.26.0) and streamlit-js-eval (0.1.5) I’m using in my environment.

Hi @pr00001, st.rerun should do instead, provided your page is in a function.

Cheers

Hi Shawn,

Oddly enough, the session_state variables don’t clear even after using st.rerun

That is expected. st.rerun does programatically the same than selecting “Rerun” in the hamburger menu, it reruns the script within the same session. Indeed very different from the browser reloading the page, that starts a new session. For that you do need JS.

Unfortunately I don’t know how to fix yous JS issue.

Is there any solution

Hi,

Can you please create an issue in the GitHub page of SJE so that we can look at it together? I just randomly found this page via Google search.

The following code works, in the latest version of SJE (0.1.7), with streamlit 1.31.0 and Python 3.10:

#!/usr/bin/env python

import streamlit as st
import streamlit_js_eval 


st.checkbox("One")
st.checkbox("Two")
st.checkbox("Three")
st.checkbox("Four")
if streamlit_js_eval.bootstrapButton("Check"):
    streamlit_js_eval.streamlit_js_eval(js_expressions="parent.window.location.reload(true)")

I don’t understand this issue fully. But would like to highlight one thing.

If your JS is not run because “button clicks” only affects components that changed : Then simply include a “comment” in your Javascript that expands to current time :slight_smile: That will ensure Streamlit runs the JS all the time.

Here is an example (See the use of double-curly as I use python’s format function).

import time
import streamlit as st
from streamlit.components.v1 import html

st.markdown('<div id="my-section-{tab_id}"></div>'.format(tab_id = "<your-tab-id>"), unsafe_allow_html=True)

#### Render the section as per your app

#### At the end, include JS that shifts attention to the section you created above

html('''
  <script>
      // Time of creation of this script = {now}.
      // The time changes everytime and hence would force streamlit to execute JS function
      function scrollToMySection() {{
          var element = window.parent.document.getElementById("my-section-{tab_id}");
          if (element) {{
              element.scrollIntoView({{ behavior: "smooth" }});
          }} else {{
              setTimeout(scrollToMySection, 100);
          }}
      }}
      scrollToMySection();
  </script>
'''.format(now=time.time(), tab_id="<your-tab-id>")

Here, I use a “tab_id” to indicate the tab in which this is being rendered. This is a good practice to have a tab_id for multi-tab application so that you can use it as a suffix to all the keys of your widgets so that widgets from multiple-tabs wont clash.

If you have a single tab application, you can ignore it. Hope this helps!