observe change of specific reactiveVal

Is it possible to run a function when a specific reactiveVal changes?
I imagine it similar to observeEvent(input$someTextInput, {}) where the observer only runs when the value in someTextInput changes.

I know that I could achieve this with a general observe({}), but then I run into a problem such as in the following toy example.

library(shiny)

shinyApp(
  fluidPage(
    textInput('i1', 'Make uppercase'),
    textInput('i2', 'Make lowercase'),
    textInput('out', 'Output (ideally not editable)')
  ),
  function(input, output, session) {
    i1 <- reactiveVal('')
    i2 <- reactiveVal('')

    observeEvent(input$i1, { i1(toupper(input$i1)) })
    observeEvent(input$i2, { i2(tolower(input$i2)) })

    observe({ print(i2()); updateTextInput(session, 'out', value = i1()) })
    observe({ print(i1()); updateTextInput(session, 'out', value = i2()) })
  }
)

Notice that without the print statements the code would work as I would want it to work. As in, when I change something in input$i1, that value gets put into my "output", and if I type something into input$i2, only that value will be put into my output.

However, with those print statements I assume that shiny wants to run both observers as soon as either reactive value i1 or i2 changes, causing the output to only contain the value inside i2.

Is there some way for me to tell shiny to only run the first observe when i1 changes and to only run the second observe when i2 changes?

I also asked this question on StackOverflow, unfortunately however it hasn't gained a lot traction so far.

dispensing with i1 and i2 reactiveVal's works for me

    out_reacval <- reactiveVal(NULL)

    observeEvent(input$i1, {out_reacval(toupper(input$i1))})

    observeEvent(input$i2, {out_reacval(tolower(input$i2))})

    observe({
      updateTextInput(session,
                      "out", 
                      value = out_reacval())
    })

EDIT

You CAN in fact observe changes in specific reactive values using observeEvent as follows.

observeEvent(i1(), { ... })

Turns out that in my previous attempts of using observeEvent I was only missing the braces after my reactive values.

Previous solution

What I just found out to work was using isolate, which, from the documentation, can read a reactive value without causing it to re-evaluate. So the two observe functions would then look as follows.

observe({ print(isolate(i2)); updateTextInput(session, 'out', value = i1()) })
observe({ print(isolate(i1)); updateTextInput(session, 'out', value = i2()) })

I don't know if that's the most elegant solution and it doesn't really get at the heart of what I wanted to achieve, but that solution will kinda let me work around my problem for now.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.