Reputation: 862
I would like the user to define an initial numeric value that is then updated (i.e. added to) by a set amount with each click of an action button. I use reactiveVal to try and make this update but am getting the dreaded Operation not allowed without an active reactive context error. I am confused because I thought using reactiveVal is doing something inside a reactive expression but obviously I am wrong.
I have looked for relevant questions/articles/tutorials but came up empty. Any advice is much appreciated. And please let me know if there is a better way of accomplishing this task, i.e. if I should be using different functions or methods.
A stripped down version of my code is below:
library(shiny)
ui <- fluidPage(
## initilize the value
numericInput('init.i','initial i',10),
## click this button to add one to the initial value
actionButton("run","Run"),
## output the current count
textOutput("cur.i")
)
server <- function(input,output) {
## define the current value according to the inital value
i <- reactiveVal({
input$init.i ## this line fails
##1 ## this line doesn't fail but value always initializes at 1
})
observeEvent(input$run, {
## make a new value by adding 1 to the current value
new.i <- i() + 1
## update the value
i(new.i)
output$cur.i <- renderText({
## print the current value
i()
})
})
}
shinyApp(ui=ui,server=server)
Upvotes: 2
Views: 2625
Reputation: 10263
The following works. As shiny reports to you, what you are trying to do is not allowed. It is the initialization of i()
where you use input$init.i
which needs the reactive context.
The wanted effect can be achieved by making another observeEvent
on the initial value you want (input$init.i
) as set your reactive value to that.
library(shiny)
ui <- fluidPage(
## initilize the value
numericInput('init.i','initial i', 10),
## click this button to add one to the initial value
actionButton("run","Run"),
## output the current count
textOutput("cur.i")
)
server <- function(input,output) {
## Define the reactive value (with no 'inital' value)
i <- reactiveVal()
## Set i() based on "initialize" input widget
observeEvent(input$init.i, {
i(input$init.i)
})
observeEvent(input$run, {
## make a new value by adding 1 to the current value
new.i <- i() + 1
## update the value
i(new.i)
})
output$cur.i <- renderText({
i()
})
}
shinyApp(ui = ui, server = server)
Also, there is no need to nest renderText
inside the observeEvent
.
Upvotes: 2