20

I'm experimenting a Shiny App to show dynamic contexts, but I cannot get renderDataTable working into a renderUi component. Below two simple replicable tests: the first one is not working, the second one without renderUi works fine, of course.

What is the conceptually difference between this two, and why the first one cannot work in Shiny?

This one not works: note that the uiOutput myTable, contains two reactive component, a selectInput and a renderDataTable, but only the selectInput is rendered.

library(shiny)
runApp(list(
    ui = fluidPage(
            fluidRow(h2("where is the table?")),
            uiOutput('myTable')
    ),
    server = function(input, output) {
            output$myTable <- renderUI({
                    fluidPage(
                            fluidRow(selectInput("test", "test", c(1,2,3))),
                            fluidRow(renderDataTable(iris))
                    )
            })
    }
))

This is fine, both selectInput and renderDataTable are rendered:

library(shiny)
runApp(list(
    ui = fluidPage(
            fluidRow(h2("where is the table?")),
            fluidRow(selectInput("test", "test", c(1,2,3))),                
            fluidRow(dataTableOutput('myTable'))
    ),
    server = function(input, output) {
            output$myTable = renderDataTable(iris)
    }
))

How to get the first scenario working?

Thanks.

EDITING after Yihui comment (thanks Yihui):

In renderUi has to be used some ui function, and not some render function: changed the sample code in the correct way, the result does not change: still no data is shown.

library(shiny)
runApp(list(
    ui = basicPage(
            uiOutput('myTable')
    ),
    server = function(input, output) {
            output$myTable <- renderUI({dataTableOutput(iris)
            })
    }
))

EDIT n.2

Just solved, got it working so:

library(shiny)
runApp(list(
    ui = fluidPage(
            mainPanel(

                    uiOutput('myTable')
            )
    ),
    server = function(input, output) {
            output$myTable <- renderUI({
                    output$aa <- renderDataTable(iris)
                    dataTableOutput("aa")
            })
    }
))

I have to save the renderTableOutput in a output variable first, and then feeding it to dataTableOutput.

Thanks for pointing me to: here

merv
  • 67,214
  • 13
  • 180
  • 245
curious
  • 201
  • 2
  • 4
  • Probably the same question as https://groups.google.com/d/msgid/shiny-discuss/d9bf5ede-7403-4a42-9831-fa9e0c0974d3%40googlegroups.com?utm_medium=email&utm_source=footer – Yihui Xie Aug 04 '15 at 22:42
  • thanks Yihui , I updated the question with the new code after reviewed your answer in https://groups.google.com/d/msgid/shiny-discuss/d9bf5ede-7403-4a42-9831-fa9e0c0974d3%40googlegroups.com?utm_medium=email&utm_source=footer. , but still no luck. – curious Aug 05 '15 at 09:57
  • I can't understand why you want to "encapsulate" `renderDataTable` inside `renderUI`... If you have to create a "complex structure", can't you use `fluidPage`/`fluidRow`/`column`/`div`/... with one or more `*output`? – Bruno Zamengo Nov 11 '17 at 14:29
  • While the second edit might work, you are redefining output$aa every time output$myTable is refreshed, instead of letting the reactive model work. The more efficient way is as described in the answer by @Thomas – Marcus Aug 16 '19 at 18:30

1 Answers1

7

It would be clearer if you split the part of datatable generation and ui generation :

library(shiny)
runApp(list(
    ui = fluidPage(
            mainPanel(
                    uiOutput('myTable')
            )
    ),
    server = function(input, output) {
            output$aa <- renderDataTable({iris})
            output$myTable <- renderUI({
                    dataTableOutput("aa")
            })
    }
))
Thomas
  • 1,164
  • 13
  • 41