0

What I want to achieve is to get access to the reactive value passed to a parent module from a child module. The reproducible example below shows the idea. When i click the button in mod_server_btn then its value should be printed out in the console (from within parent module):

library(shiny)
mod_ui_btn <-  function(id, label = "ui1UI") {
    ns <- NS(id)
    shinyUI(fluidPage(
        actionButton(ns("confirm"), "Submit", class='btn-primary')
    ))
}

mod_server_btn <- function(input, output, session) {   
    cond <- reactive({ input$confirm})
    return(cond)    
}

ui =fluidPage(
    mod_ui_btn("test"),
    uiOutput("example")
)

server=shinyServer(function(input, output, session) {   
    value <- callModule(mod_server_btn,"test")
    print(value)
    #print(value$cond) # these 3 don't work either
    #print(value()$cond)
    #print(value())  
})

shinyApp(ui=ui,server=server)

However, it doesn't work. When I click the button then I got a text: reactive({input$confirm}) in the console and it's not what I want, I need to access button value. General question is - is it possible at all to get access to reactive value in a parent module?

EDIT: @rbasa, @YBS thanks for your answers. In fact in my real app I need to return more than one reactive value to parent module. Below is slightly changed code - I added second button in mod_ui_btn - now I need to return values from both buttons to the server module. I made a list of reactives but can't get access to them using observe or output$example <-:

library(shiny)
mod_ui_btn <-  function(id, label = "ui1UI") {
    ns <- NS(id)
    shinyUI(fluidPage(
        actionButton(ns("confirm"), "Submit", class='btn-primary'),
        actionButton(ns("confirm2"), "Submit2", class='btn-primary')
    ))
}

mod_server_btn <- function(input, output, session) {

    return(
        list(
            cond = reactive({ input$confirm}),
            cond2 = reactive({ input$confirm2})
        )
    )   
}

ui =fluidPage(
    mod_ui_btn("test"),
    verbatimTextOutput("example"),
    verbatimTextOutput("example2")
)

server=shinyServer(function(input, output, session) {   
    value <- callModule(mod_server_btn,"test")  
    output$example <- renderPrint(value$cond)
    output$example2 <- renderPrint(value$cond2)
    
    observe({
        print(value$cond)  #this is how I usually catch reactives - by their name
        print(value$cond2)
    })
})

shinyApp(ui=ui,server=server)

I usually use return(list(..some reactive values)) to return more than one ractive value to other module and catch then using their names in parent module. Here it doesn't work even if I use observe. No value is returned.

mustafa00
  • 751
  • 1
  • 7
  • 28
  • 1
    Hi, check https://stackoverflow.com/questions/48882427/how-to-store-the-returned-value-from-a-shiny-module-in-reactivevalues – gdevaux Jul 16 '21 at 15:13

1 Answers1

2

You can access with value(). I would recommend to change your mod_server_btn to the one shown below, and notice the call in server. EDIT: updated for multiple variables. Try this

library(shiny)
mod_ui_btn <-  function(id, label = "ui1UI") {
  ns <- NS(id)
  shinyUI(fluidPage(
    actionButton(ns("confirm"), "Submit", class='btn-primary'),
    actionButton(ns("confirm2"), "Submit2", class='btn-primary')
  ))
}

mod_server_btn <- function(id) {
  moduleServer(id, function(input, output, session) {
    return(
      list(
        cond = reactive(input$confirm),
        cond2 = reactive(input$confirm2)
      )
    )  
    
  })
}

ui =fluidPage(
  mod_ui_btn("test"),
  verbatimTextOutput("example"),
  verbatimTextOutput("example2")
)

server=shinyServer(function(input, output, session) {   
  # value <- callModule(mod_server_btn,"test")  
  value <- mod_server_btn("test")
  output$example <- renderPrint(value$cond())
  output$example2 <- renderPrint(value$cond2())
  
  observe({
    print(value$cond())  #this is how I usually catch reactives - by their name
    print(value$cond2())
  })
})

shinyApp(ui=ui,server=server)
YBS
  • 19,324
  • 2
  • 9
  • 27
  • 1
    To add: Because `value` being returned by `mod_server_btn` is a reactive variable, it should be called from within a reactive context (`observe`, `reactive`, etc). – rbasa Jul 16 '21 at 15:43
  • Ok, so one more question - how to call it within `reactive` context? I tried to catch `value()` in `serve` module: `btn <- reactive({ value() }) print(btn())`. Unfortunately, I got an error: `Operation not allowed without an active reactive context` – mustafa00 Jul 16 '21 at 16:41
  • 1
    As stated by @rbasa in his comment, you can only call reactive variables (`value()`, `input$myvar`, etc.) within an active reactive context, such as, `observe(...)`, `observeEvent(...)`, `output$myout <- renderXXX(...)`, `reactive(...)`, etc.. To print it on the console, call within an `observe`r, as I did in my code. I am not sure why you are defining `btn <- reactive({ value() })`, as `value()` is reactive. – YBS Jul 16 '21 at 17:08
  • Ok, thanks. Last one - I need to return more than one reactive value to parent module. This is how it works in my real app. So I return them in a `list` and later catch in `observe` but it doesn't work. I added EDIT to my first post with an example, could you take a look please – mustafa00 Jul 16 '21 at 18:29