title: Using a reactive value and a reactive expression to trigger an observeEvent
body: <p>The module in the app below contains an observer that has two triggers: </p>
  
  <ol>
  <li>a reactive value <code>input$trigger1</code> (the value of a fileInput that
  is rendered inside the module server)</li>
  <li>a reactive expression <code>trigger2()</code> (the expression returns the value of an actionButton in the main app that is fed to the module).</li>
  </ol>
  
  <p>I would like the observer to print some text to the console when triggered by changes in either of these two values.</p>
  
  <p><strong>Attempt 1:</strong> I tried wrapping the triggers in a vector:</p>
  
  <pre><code>  observeEvent(c(input$trigger1, trigger2()), print('the one with the vector'), ignoreInit = T)
  </code></pre>
  
  <p>Problem: This observeEvent fires when the checkbox is checked. </p>
  
  <p>I thought this might have something to do with the module's server being called instantaneously on app start-up whereas the module's UI is only rendered if <code>input$check == TRUE</code>? I tried investigating this by printing the values of <code>input$trigger1</code> and <code>trigger2()</code> to the console using <code>observe()</code>. On start-up, the values printed to the console are <code>trigger2(): 0</code> <code>input$trigger1: NULL</code>. When the checkbox is checked, <code>input$trigger1</code> is still <code>NULL</code> but the observer fires again and prints <code>input$trigger1: NULL</code> to the console. Maybe this is due to <code>trigger1</code> not existing in the DOM on start-up?</p>
  
  <p>So I tried calling both the module's server and UI at the same time like so:</p>
  
  <pre><code>output$form = renderUI({req(input$check); modUI('mod')})
  
  observeEvent(input$check, {
      req(input$check)
      callModule(modServer, 'mod', trigger2 = reactive(input$trigger2))
  })
  </code></pre>
  
  <p>But the value of <code>input$trigger1</code> still gets printed to the console twice, this time when the checkbox is checked. I don't know why because it's <code>NULL</code> on both occasions. </p>
  
  <hr>
  
  <p><strong>Attempt 2:</strong> <a href="https://groups.google.com/d/msg/shiny-discuss/vd_nB-BH8sw/Z7IVbubtAwAJ" rel="nofollow noreferrer">According to a post in this thread</a> it occurred to me that since <code>input$trigger1</code> and <code>trigger()</code> have different classes, wrapping them in a vector might be the source of the problem (since R coerces them to the same class as pointed out by the linked post). So I tried using curly braces instead:</p>
  
  <pre><code>  observeEvent({input$trigger1; trigger2()}, print('the one with curly braces'), ignoreInit = T)
  </code></pre>
  
  <p>Problem: This observer responds to changes in <code>trigger2()</code> but not to changes in <code>input$trigger1</code>. Maybe this has something to do with the return value of the <code>eventExpr</code> (<code>trigger2()</code>) not changing if <code>input$trigger1</code> changes, but since the the <code>eventExpr</code> is a reactive expression, a change to either <code>input$trigger1</code> or <code>trigger2()</code> should invalidate it to trigger the observer as in <a href="https://groups.google.com/d/msg/shiny-discuss/vd_nB-BH8sw/n_OWksTBAgAJ" rel="nofollow noreferrer">this post</a>. </p>
  
  <hr>
  
  <p><strong>Attempt 3:</strong> I tried swapping the order of the triggers:</p>
  
  <pre><code>  observeEvent({trigger2(); input$trigger1}, print('the one with curly braces with the order swapped around'), ignoreInit = T)
  </code></pre>
  
  <p>Problem: This time the observer responds to both triggers but <em>only if</em> input$trigger1 is changed first. Otherwise, it is unresponsive.</p>
  
  <hr>
  
  <p>Here is the reproducible code:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="false" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>library("shiny")
  
  # MODULE UI ---------------------------------------------------------------
  modUI = function(id) {
    ns = NS(id)
    uiOutput(ns('ui'))
  }
  
  # MODULE SERVER -----------------------------------------------------------
  modServer = function(input, output, session, trigger2) {
    
    ns = session$ns
    
    output$ui = renderUI(fileInput(ns('trigger1'), 'Trigger1'))
    
    #OBSERVER 1 ---------------------------------------------
    observeEvent(c(input$trigger1, trigger2()), print('the one with the vector'), ignoreInit = T)
  
    # observe(print(list(`trigger2 (actionButton)` = trigger2())))
    # observe(print(list(`trigger1 (fileInput)`= input$trigger1)))
    
    #OBSERVER 2 ---------------------------------------------
    # observeEvent({input$trigger1; trigger2()}, print('the one with curly braces'), ignoreInit = T)
  
    #OBSERVER 3 ---------------------------------------------
    # observeEvent({trigger2(); input$trigger1}, print('the one with curly braces with the order swapped around'), ignoreInit = T)
    
  }
  
  
  # MAIN APP ----------------------------------------------------------------
  
  ui &lt;- fluidPage(
    checkboxInput('check', 'Show'),
    uiOutput('form'),
    actionButton('trigger2', 'Trigger 2')
  )
  
  server &lt;- function(input, output, session) {
   
    output$form = renderUI({req(input$check); modUI('mod')})
    
    # observe({
    #   req(input$check)
    #   callModule(modServer, 'mod', trigger2 = reactive(input$trigger2))
    # })
    
    callModule(modServer, 'mod', trigger2 = reactive(input$trigger2))
    
  }
  
  shinyApp(ui = ui, server = server)</code></pre>
  </div>
  </div>
  </p>
  
  <p>I've tried everything I can think of to isolate the issue to no avail so any and all guidance would be very much appreciated.</p>
  
  <p><strong>UPDATE:</strong> Maybe it has something to do with the value of <code>input$file</code> being a <code>data.frame</code>? I tried replacing <code>input$trigger1</code> with <code>trigger1()</code>, a reactiveVal that increments by 1 each time <code>input$trigger1</code> changes. This way both triggers have the same class and length (i.e. numeric(1)). The resulting observer works as expected:</p>
  
  <pre><code>modServer = function(input, output, session, trigger2) {
  
    ns = session$ns
  
    trigger1 = reactiveVal(0)
  
    observeEvent(input$trigger1, trigger1(trigger1()+1))
  
    observeEvent({trigger2(); trigger1()}, print('hello'), ignoreInit = T)
  
  }
  </code></pre>
  
  <p>I would still like to understand why attempts 1-3 didn't work though so if anyone has any insight, please post a reply.  </p>
  
  <hr>
  
  <p><strong>Explanation:</strong> As MattB pointed out, the actionButton initialises as 0 and the fileInput initialises as NULL. This means that the eventExpr for the observers in attempt 2 and 3 will evaluate to NULL as long as the input value on the last line of the expression is NULL. The eventExpr of the example in the linked post consists of a numericInput and a textInput. Since these initialise with values 0 and '' respectively, the eventExpr never returns NULL and the observer is always responsive to both inputs regardless of which is changed first. </p>