Hi, I've found myself writing most of my Shiny apps using more or less the scaffold shown in the following figure:
I use the golem
framework and the app usually starts by presenting the user different options. The selected option influences the following path, typically defined by 2 or 3 consecutive modules.
Each module has some functions associated with it.
Typically, but not always, the different paths defined by the initial options converge to a module dedicated to the reporting (frequently it just passes everything to some quarto
parametrized template).
A common module sequence could be:
- mod1: getting and preparing the data;
- mod2: elaborations and plots;
- mod3: recap of the results and adding some context;
- reporting: printing some HTML, Word, or PDF report.
Information is passed down the path defined by the module's sequence using a reactiveValues
progressively populated following the so called “stratégie du petit r”:
# at server initialisation
r <- reactiveValues()
# in option1 mod1
r$mod01_opt01 <- reactiveValues()
...
r$mod01_opt01$result1 <- result1
r$mod01_opt01$result2 <- result2
# in option2 mod1
r$mod01_opt02 <- reactiveValues()
...
r$mod01_opt02$result1 <- result1
r$mod01_opt02$result2 <- result2
...
# in option1 mod2
r$mod02_opt01 <- reactiveValues()
...
r$mod02_opt01$result1 <- result1
r$mod02_opt01$result2 <- result2
r$mod02_opt01$result3 <- result3
Now, these apps are working fine and the users seems satisfied, but I'd like to find a better way to organize my code. The problem is that the different options bring to just slightly different inputs and outputs. For example, an option could require an input selector more or less than another option, sometimes a graph or two with different axis label or style, a different statistical test and a different text accompanying the main results.
For this reason, the reasoning of the modules defined for the different options are the same, as some part of code of the functions and modules defined for the different options are more or less the same. I tried to refactor these common part in functions, but I think a deeper approach is needed: it would be nice if the code organization could reflect the real nature of these modules, as they are just more or less slight variations of the same basic idea. Any suggestions?
Thanks.