Hello all,
Long time lurker, finally had to register because I found something I can't conquer on my own.
I have been developing a forecasting application that I plan to deploy locally to people's machines using RInno to compile it and distribute. Then my users can load the application and pull in a saved project file from a remote server location, and run all the visuals in localhost.
To accomplish this, I am having certain defaults for the GUI elements load from a config file that will be stored locally with the compiled App. I would like to do this so that the defaults within the application can be updated without users modifying source code, but just a JSON file instead. This is also important because every model the application loads needs to save it's default configuration.
The below example shows how I am accomplishing this by creating a Configs object that loads from JSON when the R Instance is created, then using it to populate the arguments in the UI elements I am rendering. Because the user is allowed to select an existing model location, I also have an update function that runs when they select a new model file, and updates the values on all the sliders.
output[['NG_Billing_Lag']] <-
renderUI({
req(Configs[['Billing_Lag']])
req(input[['Payments_Type']])
v = Configs[['Billing_Lag']][['value']]
mn = Configs[['Billing_Lag']][['min']]
mx = Configs[['Billing_Lag']][['max']]
sliderInput("NG_Billing_Lag",
label = "Billing Lag Percentage",
value = v,
min = mn,
max = mx)
})
Update_Bill <- function() {
req(Configs[['Billing_Lag']])
req(input[['Payments_Type']])
v = Configs[['Billing_Lag']][['value']]
mn = Configs[['Billing_Lag']][['min']]
mx = Configs[['Billing_Lag']][['max']]
updateSliderInput(session, "NG_Billing_Lag",
label = "Billing Lag Percentage",
value = v,
min = mn,
max = mx)
}
I'm just calling the above slider with uiOutput("NG_Billing_Lag") in my ui file. The variables also reveal the structure of the JSON config file I am reading in.
So the program flow in pseudo code is:
Run R instance,
Load libraries,
Load Source files,
Configs <- Sys_Defs(getwd()) # Loads the Configs
App(ui, server)
And this is just the current version. I have been rewriting significant chunks of the program trying to fix my issue.
So the bit that is blowing my mind. This all works great (As has every iteration)... If I have started the application 2-3 times first. Each time I restart my R instance from scratch, none of the UI elements that rely on the config file will render. If I click the load button a few times to load the defaults manually, all of the slider inputs render as textbox inputs without defaults...
If I close the application and run it again, all of the UI elements render correctly. I load a model, run everything, and then none of my plotly outputs will show up (These are in a later step).
Close and run a third time, and everything works great going forward.
I know a lot less about Shiny than you all, but the best guess I have about what is happening is that the ui is not updating (Even though everything is reactive.) Shiny loads, the app starts, and then the Configs are loaded, but when they go to find the Configs with the req() they aren't finding them. When I close the application, the Configs remains in my current R instance, so rerunning it allows the app to see them, and then sliders populate.
The best I can guess is the same thing is happening in the ggplotly outputs I am using.
This is obviously suboptimal when I plan on creating and destroying the entire R instance each time the user loads the application.
Can anyone offer advice or suggestions on how to use reactive GUI elements that are populated in the manner I have described? I can't wrap my head around why the renderUI function server side is not returning a slider, even though I have tested and the req() functions are satisfied.
I'm at my wits end...