Communication between modules
By: Eric Nantz
The introductory article on modules describes that Shiny modules have more than a few similarities with general R functions, albeit with some specific components related to Shiny. In addition, modules can range in complexity and often need to communicate with each other in large-scale applications. While a basic use of modules already helps manage complexity greatly, there are some useful techniques you can employ to ensure a smooth and clear model for communication between modules themselves and with your overall Shiny application. Following these best practices with modules enables your application’s code base to be more organized, easier to understand, and facilitate concurrent development workstreams on different components. In the remainder of this article, we will illustrate how these techniques are applied to a specific application utilizing modules.
This application lets the user create two side-by-side scatterplots, each with potentially different variables selected for the X and Y axes. The app uses two modules, one handling the variable selection and the other producing the side-by-side scatterplots.
Here is the variable selection module user interface:
Notice the use of roxygen comments before the
varselect_mod_ui module definition. Writing documentation of a module’s inputs and return values is a powerful way to make clear the purpose of the module. Even if you use a different format for documenting the module parameters, the key point is to document when possible!
Now let’s examine the server logic of this module:
The purpose of the server-side component is to assemble the variable choices made by the user, and the return object is a named list with slots corresponding to the different variable selections. While the processing of this module is trivial (i.e. nothing more than obtaining the input values), constructing the return value in this manner is a straight-forward approach to articulating the intent. In this case, the module acts like an accessor to capture the inputs explicitely. Lastly, this module reinforces the idea that reactive expressions are typically the most portable format for passing reactive information between modules.
Communication between modules
Below is the server logic of the visualization module. This module makes use of a simple function,
scatter_sales(), to create the scatterplot. Details on this function as well as the module that builds the user interface for the visualization (
scatterplot_mod_ui) are shown in the app code, but omitted here.
We can now see the benefits of documenting the variable module’s parameters and clear specification of the return object. The documentation for the
plot2vars parameters indicates the object type and more importantly the reactive components of the x and y variable names. Within the module code, it is important to reference the variable names correctly by using
plot1vars$yvar() instead of
plot1vars()$yvar, which is a common error in these situations.
Below is the user interface and server code for the application overall. Complete code including module definitions and helper functions can be found alongside the deployed app here.
By utilizing the techniques illustrated above, the application wrapper code is well-organized and easy to manage. The module for selecting variables could easily be called multiple times, and any enhancements made to that module could be performed in parallel to other development workstreams. For instance, if a team of developers was authoring this application, a subset of the team may improve the plot aesthetics in the scatterplot module while another group tweaks the variable selection module appearance. In addition, the documentation of the module inputs and return values ensures clear communication of the purpose of the module and can even be incorporated in new applications or packages.
If you have questions about this article or would like to discuss ideas presented here, please post on RStudio Community. Our developers monitor these forums and answer questions periodically. See help for more help with all things Shiny.