Search code examples
rshinyreactiveobservers

Wrong renderText output on use of conditionalPanel (shiny)


I am facing problems in rendering an output based on input in conditional panels. Below I have written a modified version of my code where I have removed all the extra stuff that was not relevant to the question.

The ui.R is

library(shiny)

shinyUI(fluidPage(

titlePanel("Art and R"),

sidebarLayout(
    sidebarPanel(

        selectInput(
            "colspa", "Color space", choices = list("A" = "a", "B" = "b"), selected = 1
        ),  

        conditionalPanel(
            condition = "input.colspa == 'a'", selectInput(
                "colchoice", "Color choice", choices = list("ONE" = "one", "TWO" = "two", "THREE" = "three"), selected = 1
            )
        ),

        conditionalPanel(
            condition = "input.colspa == 'b'", selectInput(
                "colchoice", "Color choice", choices = list("FOUR" = "four", "FIVE" = "five", "SIX" = "six"), selected = 1
            )
        ),

        actionButton("btn", "Show!")
    ),

    mainPanel(
        textOutput("distPlot")
    )
)
))

And the server.R is

library(shiny)

shinyServer(function(input, output) {
str2 <<- ""
str3 <<- ""
getResults1 <- observeEvent(input$btn, {
    str2 <<- (paste0(input$colspa))
})

getResults2 <- observeEvent(input$btn, {
    str3 <<- (paste0(input$colchoice))
})

calculate <- eventReactive(input$btn, {
    str1 <<- paste0(str2, str3)
    return(str1)
})

output$distPlot <- renderText({
    calculate()
})
})

If I run this application, I get correct results when colspa is "a" but as soon as I change colspa to "b" from selectInput, The output rendered is not what I want. Below is an example of the problem.

Correct output when selectInput is A Wrong output when selectInput is B


Solution

  • You shouldn't use the same ID for two different outputs. The reason for failing was that "colchoice" was still bound to the first selectInput, since that had the same ID as the second. The following is a working example with updateSelectInput. Note that you need an additional session argument in the Server for that.

    ui <- shinyUI(fluidPage(
    
      titlePanel("Art and R"),
    
      sidebarLayout(
        sidebarPanel(
          # first select input
          selectInput(
            "colspa", "Color space", choices = list("A" = "a", "B" = "b"), selected = "a"
          ),
          # second select input 
          selectInput(
              "colchoice", "Color choice", choices = list("ONE" = "one", "TWO" = "two", "THREE" = "three"), selected = "one"
          ),
    
          actionButton("btn", "Show!")
        ),
    
        mainPanel(
          textOutput("distPlot")
        )
      )
    ))
    
    server <- shinyServer(function(input, output, session) {
    
      # change choices of input$colchoice depending on input$colspa
      observeEvent(input$colspa, {
        if(input$colspa == "a") myChoices <- c("ONE" = "one", "TWO" = "two", "THREE" = "three")
        else myChoices <- c("FOUR" = "four", "FIVE" = "five", "SIX" = "six")
    
        updateSelectInput(session, "colchoice", choices = myChoices)
      })
    
    
      # display selected choices upon click of input$btn
    
      calculate <- eventReactive(input$btn, {
        paste0(input$colspa, input$colchoice)
      })
    
      output$distPlot <- renderText({
        calculate()
      })
    })
    shinyApp(ui, server)
    

    enter image description here