shiny icon indicating copy to clipboard operation
shiny copied to clipboard

autoreload doesn't load with Shiny modules

Open mik3y64 opened this issue 4 years ago • 10 comments

My R/ dir have three files

  • R/app.R
  • R/shiny_run.R
  • R/my_module.R

autoreload works without module

# app.R
library(shiny)

ui <- fluidPage(
  selectInput("sample_input", "changeLabel", choices = letters[1:3])
)
server <- function(input, output, session) {
  NULL
}
shinyApp(ui = ui, server = server)
# shiny_run.R
options(shiny.autoreload = TRUE)
shiny::runApp()

Editing the "changeLabel" in selectInput() does the change the label.

autoreload doesn't work with module

# my_module.R
moduleUI <- function(id) { 
  ns <- NS(id)
  selectInput(ns("sample_input"), "changeLabel", choices = letters[1:3])
}
moduleServer <- function(input, output, session) {
  NULL
}
# app.R
library(shiny)
source("my_module.R")

ui <- fluidPage(
  moduleUI('test')
)
server <- function(input, output, session) {
  callModule(moduleServer, 'test')
}
shinyApp(ui = ui, server = server)
# shiny_run.R
options(shiny.autoreload = TRUE)
shiny::runApp()

Editing the "changeLabel" in selectInput() does refresh the Shiny application but "changeLabel" does not change at all.

mik3y64 avatar Nov 26 '19 10:11 mik3y64

Maybe, a small hint how one can further specify the issue. As far as i see, the issue is rather wth source(...).

Note, if you put the modules from my_module.R to app.R and changes the modules in there, you get the desired updates at run time.

However, if you put a random, (non-moduled) ui component in "my_module.r"source it and change it at run time, it wont get updated.

It gets even more interesting.

  • If you look in the docu: https://shiny.rstudio.com/reference/shiny/latest/shinyOptions.html, you will see that the file should be monitored:

continually monitored for changes to files that have the extensions: r, htm, html, js, css, png, jpg, jpeg, gif. If any changes are detected, all connected Shiny sessions are reloaded.

  • And in fact: If you look closely, the site is refreshed, the ui change just does not take place.

  • However, if you change something within app.R after an edit in the sourced file, both edits can be seen.

tldr; Long text without a clear solution. But it might be of help for further debugging i hope.

Toniiiio avatar Dec 19 '19 23:12 Toniiiio

@Timag , did you ever resolve this? In my shiny app, I am source()-ing a utils.r file from my app.r script. I see the UI refresh in the browser upon saving utils.r, but the changes are not loaded in until app.r is modified and saved. I believe this is the exact issue you describe here.

erikriverson avatar Feb 19 '20 18:02 erikriverson

@erikriverson sry, no.

Toniiiio avatar Feb 19 '20 19:02 Toniiiio

I had the same issue, but as as a workaround I included my source functions also inside the main app's server function. This will reload the module files everytime the autoreload is triggered. You need to set local = TRUE, otherwise the modules will end up in the global environment, where server function doesn't seem to find them. These extra source functions can be later removed from the production version of the app.

server <- function(input, output, session) {
  source("my_module.R", local = TRUE)
  ## app code...
}

itkonen avatar Sep 25 '20 11:09 itkonen

I'm also encountering this issue. I've set some debug points to ensure that initAutoReloadMonitor is picking up my files, and it is.

nlarusstone avatar Mar 26 '21 23:03 nlarusstone

I had the same issue, but as as a workaround I included my source functions also inside the main app's server function. This will reload the module files everytime the autoreload is triggered. You need to set local = TRUE, otherwise the modules will end up in the global environment, where server function doesn't seem to find them. These extra source functions can be later removed from the production version of the app.

server <- function(input, output, session) {
  source("my_module.R", local = TRUE)
  ## app code...
}

Thanks @itkonen , it is a workaround, but a incredibly useful one.

GitHunter0 avatar Jan 25 '22 13:01 GitHunter0

I've got this for now, in the main server function:

    server_env = environment()
    lapply(
        list.files(path = "R", pattern = ".*\\.R$", full.names = TRUE),
        source,
        local = server_env
    )

The catch is that this does not lead to the ui parts being updated. Ultimately, I still always have to touch the app.R to get a full reload.

epruesse avatar Jun 22 '22 16:06 epruesse

It would be great to have this work out-of-the-box here, as it also would then work within a golem or Rhino project.

asadow avatar Mar 05 '23 22:03 asadow

Bumping this, really becomes an issue when you are building larger apps

taimur38 avatar Nov 23 '23 20:11 taimur38