1

I am looking for a bit of help understanding shiny reactivity - my very basic example works, but I have a feeling it's the incorrect way to do things. I have read through the example here - which explained the different behaviours of observe versus reactive. But in my example I have used them in combination - and I would like to understand if and why, that is something I should not be doing!

My approach - is this incorrect?

I have captured the reactive value of my action button in the module (see full code below), and assigned it to my reactiveValues list using reactive().

navigation_values <- reactiveValues()
navigation_values$button1 = reactive(input$navigate)

This reactive list then gets returned to the app server, where I then access the value using navigation_values$button1(). This works (for this small example) - but is different to all the shiny documentation/vignettes, where I see instead...

 observeEvent(input$navigate, {
      navigation_values$button1 = input$navigate
    })

And then the value accessed via navigation_values$button1

Any help appreciated! I'm not sure if this is a "philosophical" question, or if my approach would immediately cause problems if I were to extend it to a more thorough example.

Full code

library(shiny)
library(shinydashboard)

# update values module -------------------------------------

module_ui <- function(id){
  ns <- NS(id)
  tagList(
    actionButton(inputId = ns("navigate"),
                 label = "Go to page 2")
  )
}

module_server <- function(id){
  
  moduleServer(id, function(input, output, session){

    navigation_values <- reactiveValues()
    navigation_values$button1 = reactive(input$navigate)
    
    return(navigation_values)
    
  })

}

# UI  --------------------------------------------

sidebar <- dashboardSidebar(
  sidebarMenu(
    id = "mastertabs",
    menuItem(
      text = "Page 1",
      tabName = "page1"),
    menuItem(
      text = "Page 2",
      tabName = "page2")))

body <- dashboardBody(
  tabItems(
    tabItem(
      tabName = "page1",
      fluidPage(module_ui("mymodule"))
    )))

ui <- dashboardPage(
  dashboardHeader(title = "PRACTICE"),
  sidebar,
  body
)

# Server ------------------------

server <- function(input, output, session){
  
  navigation_values <- module_server("mymodule")
  
  observeEvent(navigation_values$button1(), {
    updateTabsetPanel(session, inputId = "mastertabs", selected = "page2")
  })

}

shinyApp(ui = ui, server = server)
Cath
  • 57
  • 4

1 Answers1

0

I think the best approach is simply:

moduleServer(id, function(input, output, session){

    return(reactive(input$navigate)

})

Then, in your app, just call:

 navigation_values()
SmokeyShakers
  • 3,372
  • 1
  • 7
  • 18
  • Thanks! I see the simplicity of this - however I should have also mentioned... I am intentionally using a `reactiveValues` list, because my use case application has many modules, and many action buttons. My idea was to store all those values in one object, to help with code maintenance etc. So my question is how I should go about storing the value in the `reactiveValues` object. – Cath May 20 '22 at 14:43
  • Ah, of course. Yes, then the reactive call here is redundant. `navigation_values$button1 = reactive(input$navigate)` unless you had some need to access only the reactive function for the input (not its value), e.g. in a higher order function. – SmokeyShakers May 20 '22 at 14:54
  • OK so given I'm only interested in the value of the input (not the reactive expression itself) - it's overkill to store the whole expression? And that's because `navigation_values$button1 = input$navigate` captures the value of the actionButton whereas `navigation_values$button1 = reactive(input$navigate)` captures the entire reactive function (expression?)? – Cath May 20 '22 at 16:20