Home > Software engineering >  How to put a reactive value inside a reactiveVal() in a shiny app
How to put a reactive value inside a reactiveVal() in a shiny app

Time:01-28

I have the shiny app below in which I want to color my dynamic box based on the shiny widget that exists in it. The shiny widget contains 2 words. If the selected word is "setosa" the box is red otherwise its green. Im trying to make it work but I get: 'match' requires vector arguments. I think that the issue is on how I try to make my reactiveVal() reactive. The datnum dataset must be in a reactive context since in my original app is dynamic

## app.R ##
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    tags$head(
      tags$style(HTML("
                      #mybox2Red{border-top-style: none; border-left-color: red; border-left-style: solid;}
                      #mybox2Green{border-top-style: none; border-left-color: green; border-left-style: solid;}
                      "))
      ),
    uiOutput("box2")
      )
      )


server <- function(input, output) {
  
  datnum<-reactive({
    setosa<-c(0,5)
    versicolor<-c(0,5)
    redgreen<-data.frame(setosa,versicolor)
  })
  
  
  Value3<-  reactive({reactiveVal(colnames(datnum()[1]))})
    
  
  observeEvent(input$mm, Value3(input$mm))
  
  valuerange<-reactive({
    iris<-subset(iris,Species==Value3())
    unique(iris$Species)
  })
  
  
  output$box2 <- renderUI({
    
    box(
      id=ifelse(valuerange()=="setosa", "mybox2Red", "mybox2Green"),
      title = "title", 
      closable = TRUE, 
      width = 10,
      status = "danger", 
      solidHeader = F, 
      collapsible = TRUE,
      collapsed = T,
      pickerInput(
        inputId = "mm",
        label = "Select attribute",
        choices = colnames(datnum()),
        selected=Value3(),
        multiple = F
        
      )
    )
  })
}

shinyApp(ui, server)

CodePudding user response:

I believe what you're looking for is simply

Value3<-  reactiveVal()

As you have it originally (reactive({reactiveVal(colnames(datnum()[1]))})) you define Value3 as a reactive but then try to treat is a reactiveVal when redefine it in the observer later (Value3(input$mm)). Just initialize it to a null reactiveVal and then let the observer do its magic.

A reactive will automatically recalculate itself. A reactiveVal must be explicitly assigned. An input is already essentially a reactiveVal so I'm not sure why you are wrapping it within Value3 (perhaps the non-reprex has more complexity) but you also just as well wrap it in the reactive and drop the observeEvent line

Value3 <- reactive(input$mm)

This could be preferential if you want to leverage caching and lazy evaluation. If you want eager evaluation, stick with the observeEvent

CodePudding user response:

If I understand what you want to do, just remove the reactive, i.e.:

  Value3 <- reactiveVal( colnames(datnum()[1]) )
  • Related