Confused by scoping rules


Hi all,

Apologies if this question was previously answered, but I am a shiny new-bie! :wink:

I am using a to sync a plot and a table display of a single record from a dataset in the global environment. I tried this:

# Define server logic ----
server <- function(input, output) {
  RecordPointer <- 1

  observeEvent(input$Next, {
    RecordPointer <- RecordPointer+1
  observeEvent(input$Prev, {
    if(RecordPointer > 2) RecordPointer <- RecordPointer - 1
  output$table <- DT::renderDataTable(DT::datatable(Discordant[RecordPointer,],
    options = list(pageLength = 1))
  output$plot <- renderPlot({
    i <- RecordPointer


but the record displayed and plotted stays the same no matter how many times I hit next or prev…

I will greatly appreciate any hint that helps me see the error in my ways!

Alternatively, I will also appreciate if someone can help me how to access the “current” record in the DT, that way I will not have to construct my own navigator.



To access which record is currently selected in DT you can use input$tableId_rows_selected. See more details here:


explained in first observer but same logic applies to the rest.

server <- function(input, output) {

  RecordPointer <- 1 #created in serverFunction environment, additionally i recommend using 1L as it assigns integer

  observeEvent(input$Next, {
    RecordPointer <- RecordPointer+1 #RecordPointer created inside observerEvent environment
    # value assigned from RecordPointer in serverFunction environment as RecordPointer inside current environment 
    # doesnt exist yet
    # RecordPointer from this environment gets deleted when function call ends
    # to change value in serverFunction use:
    assign(x = 'RecordPointer',value = RecordPointer+1L , envir = parent.env(environment()))


To modify a variable in the parent environment, it’s easier to just use <<- rather than assign. But in this case I wouldn’t even do that; since RecordPointer is just a normal variable it will not trigger reactivity.

Instead, use a reactiveVal:

function(input, output, session) {
  RecordPointer <- reactiveVal()

  observeEvent(input$Next, {
    RecordPointer(RecordPointer() + 1)

  output$plot <- renderPlot({
    i <- RecordPointer()


Thank you all!

These explanations clear the fog I had regarding the scope of the server
function and the event handler functions.

I also appreciate the intro to reactive functions. That explains that when
I tried using <<- to increase the record counter in the event handler it
did not work either.

Thanks again!