Super Solutions for Shiny Apps #4: Using R6 Classes

Estimated time:
time
min

<h2><strong>TL;DR</strong></h2> Why use object-oriented programming in Shiny applications? It'll help organizize organize the code in your application!   <img class="aligncenter size-full wp-image-2955" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b022c092a26c843b64bc3c_organizize-your-shiny-apps.webp" alt="one of these days i'm gonna get organizized" width="590" height="410" /> <h2><strong>Organize Your Shiny Code with Object-Oriented Programming</strong></h2> Classes are used widely in all R programming -- usually the S3 ones. Even if you’ve never heard of them, as an R user you’re for sure familiar with object classes like <i>data.frame</i>. The magic of classes makes same functions (like <i>print</i> or <i>plot</i>) operate differently for specific cases. This system also allows you to define methods and attributes dedicated for object - thus basing your code around objects, not functions. How can it be useful in Shiny app? Well, for advanced apps it helps you in organizing your code. When designing a Shiny app it is often the way it should work - usually the user is interacting with some specific data structure that requires e.g. exploration, modification, saving, exporting etc. What is more, Shiny apps contain much more additional stuff required for production-ready applications that will work great when being organizized organized in a class system. Let us go through this functionality.  You may wonder what objects can be stored in the app. Well, there might be ‘settings’ with private fields of configuration and public methods to get or modify them. There might be a ‘user data’ class with all of the values specific for the logged-in user and methods to read them. The data probably comes from some database, the connection to which may be another class, as well as the log builder. And some specific spatial dataset used on this new screen that required unusual functions to operate on. And so on… The point is this: once your app grows with new functionalities you will end up with tons of functions organized between multiple ‘utils-something’ scripts and a bunch of lists with stored current values. Using object oriented programming (OOP) in the Shiny App allows developers to organize the code in the packs <b>object-attributes-functions</b>. It will introduce a clear system of getting the current state of the piece of functionality, the operations that can be performed with it, the auxiliary functions, the initial state of the object (which can depend on the particular user access rights, which might be very useful!). In Appsilon we recommend using an R6 class system. What is R6? To make a long story short, it is a modern, fast and simple implementation of object-oriented programming (OOP) in R. To learn more about the system, check <a href="https://adv-r.hadley.nz/r6.html">Hadley’s Advanced R book</a>. How do we recommend organizing the code with the class system introduced? Keep each class in the separated script with a name similar to the class name, and store them all together in a folder separated from other code e.g. <i>ui</i> definitions of modules (folders structure might be problematic when developing a Shiny app as a package - doing it has pros and cons. In Appsilon we do not package our apps as it gives us more freedom with building the apps). Once the code is imported (either in a package or separately with e.g. <i>modules::use</i> function) the class needs to be initialized in the <i>global.R</i> script with the <i>new()</i> method (automatically available for all classes) and attached to some object. The class, its attributes and methods can be used everywhere in the code - but you’ve gained a clear overview of the purpose of the method call and what object it modifies and where to find the details about this particular functionality. Here’s a practice example:  <figure class="highlight"> <pre class="language-r"><code class="language-r" data-lang="r"># in global.R logger_manager = LoggerManager$new() <br># in logger_manager.R LoggerManager &lt;- R6Class(  "LoggerManager",  private = list(    ...  ),  public = list(    initialize = function() {      ...    },    log_input = function(     ...    ) {      ...    }  ) ) </code></pre> </figure> It might not be obvious from the beginning which classes will be used in the code - Shiny apps often start as a simple prototype to finally become some advanced production solution. Just don’t be afraid and always have in mind that classes are a good solution to organize your code once your app goes big!  Thanks for reading!  Questions? Comments? Add them below and/or find me on Twitter <a href="https://twitter.com/DubelMarcin">@dubelmarcin</a>.  You can also check out the other posts in the “Super Solutions for Shiny Architecture Series”: <a href="https://appsilon.com/super-solutions-for-shiny-architecture-1-of-5-using-session-data/">#1 Using Session Data, </a><a href="https://appsilon.com/super-solutions-for-shiny-architecture-2-javascript-is-your-friend/">#2 Javascript is your friend, and</a> <a href="https://appsilon.com/super-solutions-for-shiny-architecture-3-5-softcoding-constants-in-the-app/?nabe=4825491004194816:1">#3 Softcoding Constants in the App</a>.    <h2>Follow Appsilon Data Science on Social Media</h2> <a href="https://twitter.com/appsilon">@Appsilon</a> is on twitter! Check us out on our <a href="https://www.facebook.com/appsilondatascience/">Facebook</a> page! Check us out on <a href="https://www.linkedin.com/company/appsilon">LinkedIn</a>! And don’t forget to sign up for our <a href="https://appsilon.com/blog/">newsletter</a>. Check out our R Shiny <a href="https://appsilon.com/opensource/">open source</a> packages!

Contact us!
Damian's Avatar
Damian Rodziewicz
Head of Sales
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
r
tutorials
shiny dashboards