Files
shiny/reference/bindEvent.html
2025-12-03 21:28:29 +00:00

273 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Make an object respond only to specified reactive events — bindEvent • shiny</title><!-- jquery --><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><!-- Bootstrap --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha256-bZLfwXAP04zRMK2BjiO8iu9pf4FbLqX6zitd+tIvLhE=" crossorigin="anonymous"><script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha256-nuL8/2cJ5NDSSwnKD8VqreErSWHtnEP9E7AySL+1ev4=" crossorigin="anonymous"></script><!-- bootstrap-toc --><link rel="stylesheet" href="../bootstrap-toc.css"><script src="../bootstrap-toc.js"></script><!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous"><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- pkgdown --><link href="../pkgdown.css" rel="stylesheet"><script src="../pkgdown.js"></script><meta property="og:title" content="Make an object respond only to specified reactive events — bindEvent"><meta property="og:description" content="Modify an object to respond to &quot;event-like&quot; reactive inputs, values, and
expressions. bindEvent() can be used with reactive expressions, render
functions, and observers. The resulting object takes a reactive dependency on
the ... arguments, and not on the original object's code. This can, for
example, be used to make an observer execute only when a button is pressed.
bindEvent() was added in Shiny 1.6.0. When it is used with reactive() and
observe(), it does the same thing as eventReactive() and
observeEvent(). However, bindEvent() is more flexible: it can be combined
with bindCache(), and it can also be used with render functions (like
renderText() and renderPlot())."><meta property="og:image" content="/logo.png"><!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]--></head><body data-spy="scroll" data-target="#toc">
<div class="container template-reference-topic">
<header><div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand">
<a class="navbar-link" href="../index.html">shiny</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="">1.12.1</span>
</span>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"><li>
<a href="../reference/index.html">Reference</a>
</li>
<li>
<a href="../news/index.html">Changelog</a>
</li>
</ul><ul class="nav navbar-nav navbar-right"><li>
<a href="https://github.com/rstudio/shiny/" class="external-link">
<span class="fab fa-github fa-lg"></span>
</a>
</li>
</ul></div><!--/.nav-collapse -->
</div><!--/.container -->
</div><!--/.navbar -->
</header><div class="row">
<div class="col-md-9 contents">
<div class="page-header">
<h1>Make an object respond only to specified reactive events</h1>
<small class="dont-index">Source: <a href="https://github.com/rstudio/shiny/blob/rc-v1.12.1/R/bind-event.R" class="external-link"><code>R/bind-event.R</code></a></small>
<div class="hidden name"><code>bindEvent.Rd</code></div>
</div>
<div class="ref-description">
<p>Modify an object to respond to "event-like" reactive inputs, values, and
expressions. <code>bindEvent()</code> can be used with reactive expressions, render
functions, and observers. The resulting object takes a reactive dependency on
the <code>...</code> arguments, and not on the original object's code. This can, for
example, be used to make an observer execute only when a button is pressed.</p>
<p><code>bindEvent()</code> was added in Shiny 1.6.0. When it is used with <code><a href="reactive.html">reactive()</a></code> and
<code><a href="observe.html">observe()</a></code>, it does the same thing as <code><a href="observeEvent.html">eventReactive()</a></code> and
<code><a href="observeEvent.html">observeEvent()</a></code>. However, <code>bindEvent()</code> is more flexible: it can be combined
with <code><a href="bindCache.html">bindCache()</a></code>, and it can also be used with <code>render</code> functions (like
<code><a href="renderPrint.html">renderText()</a></code> and <code><a href="renderPlot.html">renderPlot()</a></code>).</p>
</div>
<div id="ref-usage">
<div class="sourceCode"><pre class="sourceCode r"><code><span><span class="fu">bindEvent</span><span class="op">(</span></span>
<span> <span class="va">x</span>,</span>
<span> <span class="va">...</span>,</span>
<span> ignoreNULL <span class="op">=</span> <span class="cn">TRUE</span>,</span>
<span> ignoreInit <span class="op">=</span> <span class="cn">FALSE</span>,</span>
<span> once <span class="op">=</span> <span class="cn">FALSE</span>,</span>
<span> label <span class="op">=</span> <span class="cn">NULL</span></span>
<span><span class="op">)</span></span></code></pre></div>
</div>
<div id="arguments">
<h2>Arguments</h2>
<dl><dt id="arg-x">x<a class="anchor" aria-label="anchor" href="#arg-x"></a></dt>
<dd><p>An object to wrap so that is triggered only when a the specified
event occurs.</p></dd>
<dt id="arg--">...<a class="anchor" aria-label="anchor" href="#arg--"></a></dt>
<dd><p>One or more expressions that represents the event; this can be a
simple reactive value like <code>input$click</code>, a call to a reactive expression
like <code>dataset()</code>, or even a complex expression inside curly braces. If
there are multiple expressions in the <code>...</code>, then it will take a dependency
on all of them.</p></dd>
<dt id="arg-ignorenull">ignoreNULL<a class="anchor" aria-label="anchor" href="#arg-ignorenull"></a></dt>
<dd><p>Whether the action should be triggered (or value
calculated) when the input is <code>NULL</code>. See Details.</p></dd>
<dt id="arg-ignoreinit">ignoreInit<a class="anchor" aria-label="anchor" href="#arg-ignoreinit"></a></dt>
<dd><p>If <code>TRUE</code>, then, when the eventified object is first
created/initialized, don't trigger the action or (compute the value). The
default is <code>FALSE</code>. See Details.</p></dd>
<dt id="arg-once">once<a class="anchor" aria-label="anchor" href="#arg-once"></a></dt>
<dd><p>Used only for observers. Whether this <code>observer</code> should be
immediately destroyed after the first time that the code in the observer is
run. This pattern is useful when you want to subscribe to a event that
should only happen once.</p></dd>
<dt id="arg-label">label<a class="anchor" aria-label="anchor" href="#arg-label"></a></dt>
<dd><p>A label for the observer or reactive, useful for debugging.</p></dd>
</dl></div>
<div id="details">
<h2>Details</h2>
<p>Shiny's reactive programming framework is primarily designed for calculated
values (reactive expressions) and side-effect-causing actions (observers)
that respond to <em>any</em> of their inputs changing. That's often what is
desired in Shiny apps, but not always: sometimes you want to wait for a
specific action to be taken from the user, like clicking an
<code><a href="actionButton.html">actionButton()</a></code>, before calculating an expression or taking an action. A
reactive value or expression that is used to trigger other calculations in
this way is called an <em>event</em>.</p>
<p>These situations demand a more imperative, "event handling" style of
programming that is possiblebut not particularly intuitiveusing the
reactive programming primitives <code><a href="observe.html">observe()</a></code> and <code><a href="isolate.html">isolate()</a></code>. <code>bindEvent()</code>
provides a straightforward API for event handling that wraps <code>observe</code> and
<code>isolate</code>.</p>
<p>The <code>...</code> arguments are captured as expressions and combined into an
<strong>event expression</strong>. When this event expression is invalidated (when its
upstream reactive inputs change), that is an <strong>event</strong>, and it will cause
the original object's code to execute.</p>
<p>Use <code>bindEvent()</code> with <code><a href="observe.html">observe()</a></code> whenever you want to <em>perform an action</em>
in response to an event. (This does the same thing as <code><a href="observeEvent.html">observeEvent()</a></code>,
which was available in Shiny prior to version 1.6.0.) Note that
"recalculate a value" does not generally count as performing an action
use <code><a href="reactive.html">reactive()</a></code> for that.</p>
<p>Use <code>bindEvent()</code> with <code><a href="reactive.html">reactive()</a></code> to create a <em>calculated value</em> that
only updates in response to an event. This is just like a normal <a href="reactive.html">reactive expression</a> except it ignores all the usual invalidations that
come from its reactive dependencies; it only invalidates in response to the
given event. (This does the same thing as <code><a href="observeEvent.html">eventReactive()</a></code>, which was
available in Shiny prior to version 1.6.0.)</p>
<p><code>bindEvent()</code> is often used with <code><a href="bindCache.html">bindCache()</a></code>.</p>
</div>
<div id="ignorenull-and-ignoreinit">
<h2>ignoreNULL and ignoreInit</h2>
<p><code>bindEvent()</code> takes an <code>ignoreNULL</code> parameter that affects behavior when
the event expression evaluates to <code>NULL</code> (or in the special case of an
<code><a href="actionButton.html">actionButton()</a></code>, <code>0</code>). In these cases, if <code>ignoreNULL</code> is <code>TRUE</code>, then it
will raise a silent <a href="validate.html">validation</a> error. This is useful behavior
if you don't want to do the action or calculation when your app first
starts, but wait for the user to initiate the action first (like a "Submit"
button); whereas <code>ignoreNULL=FALSE</code> is desirable if you want to initially
perform the action/calculation and just let the user re-initiate it (like a
"Recalculate" button).</p>
<p><code>bindEvent()</code> also takes an <code>ignoreInit</code> argument. By default, reactive
expressions and observers will run on the first reactive flush after they
are created (except if, at that moment, the event expression evaluates to
<code>NULL</code> and <code>ignoreNULL</code> is <code>TRUE</code>). But when responding to a click of an
action button, it may often be useful to set <code>ignoreInit</code> to <code>TRUE</code>. For
example, if you're setting up an observer to respond to a dynamically
created button, then <code>ignoreInit = TRUE</code> will guarantee that the action
will only be triggered when the button is actually clicked, instead of also
being triggered when it is created/initialized. Similarly, if you're
setting up a reactive that responds to a dynamically created button used to
refresh some data (which is then returned by that <code>reactive</code>), then you
should use <code>reactive(...) %&gt;% bindEvent(..., ignoreInit = TRUE)</code> if you
want to let the user decide if/when they want to refresh the data (since,
depending on the app, this may be a computationally expensive operation).</p>
<p>Even though <code>ignoreNULL</code> and <code>ignoreInit</code> can be used for similar purposes
they are independent from one another. Here's the result of combining
these:</p>
<dl><dt><code>ignoreNULL = TRUE</code> and <code>ignoreInit = FALSE</code></dt>
<dd><p>This is the default. This combination means that reactive/observer code
will run every time that event expression is not
<code>NULL</code>. If, at the time of creation, the event expression happens
to <em>not</em> be <code>NULL</code>, then the code runs.</p></dd>
<dt><code>ignoreNULL = FALSE</code> and <code>ignoreInit = FALSE</code></dt>
<dd><p>This combination means that reactive/observer code will
run every time no matter what.</p></dd>
<dt><code>ignoreNULL = FALSE</code> and <code>ignoreInit = TRUE</code></dt>
<dd><p>This combination means that reactive/observer code will
<em>not</em> run at the time of creation (because <code>ignoreInit = TRUE</code>),
but it will run every other time.</p></dd>
<dt><code>ignoreNULL = TRUE</code> and <code>ignoreInit = TRUE</code></dt>
<dd><p>This combination means that reactive/observer code will
<em>not</em> at the time of creation (because <code>ignoreInit = TRUE</code>).
After that, the reactive/observer code will run every time that
the event expression is not <code>NULL</code>.</p></dd>
</dl></div>
<div id="types-of-objects">
<h2>Types of objects</h2>
<p><code>bindEvent()</code> can be used with reactive expressions, observers, and shiny
render functions.</p>
<p>When <code>bindEvent()</code> is used with <code><a href="reactive.html">reactive()</a></code>, it creates a new reactive
expression object.</p>
<p>When <code>bindEvent()</code> is used with <code><a href="observe.html">observe()</a></code>, it alters the observer in
place. It can only be used with observers which have not yet executed.</p>
</div>
<div id="combining-events-and-caching">
<h2>Combining events and caching</h2>
<p>In many cases, it makes sense to use <code>bindEvent()</code> along with
<code><a href="bindCache.html">bindCache()</a></code>, because they each can reduce the amount of work done on the
server. For example, you could have <a href="sliderInput.html">sliderInput</a>s <code>x</code> and <code>y</code> and a
<code><a href="reactive.html">reactive()</a></code> that performs a time-consuming operation with those values.
Using <code><a href="bindCache.html">bindCache()</a></code> can speed things up, especially if there are multiple
users. But it might make sense to also not do the computation until the
user sets both <code>x</code> and <code>y</code>, and then clicks on an <a href="actionButton.html">actionButton</a> named
<code>go</code>.</p>
<p>To use both caching and events, the object should first be passed to
<code><a href="bindCache.html">bindCache()</a></code>, then <code>bindEvent()</code>. For example:</p>
<p></p><div class="sourceCode"><pre><code><span id="cb1-1"><a href="#cb1-1" tabindex="-1"></a>r <span class="ot">&lt;-</span> <span class="fu">reactive</span>({</span>
<span id="cb1-2"><a href="#cb1-2" tabindex="-1"></a> <span class="fu">Sys.sleep</span>(<span class="dv">2</span>) <span class="co"># Pretend this is an expensive computation</span></span>
<span id="cb1-3"><a href="#cb1-3" tabindex="-1"></a> input<span class="sc">$</span>x <span class="sc">*</span> input<span class="sc">$</span>y</span>
<span id="cb1-4"><a href="#cb1-4" tabindex="-1"></a> }) <span class="sc">%&gt;%</span></span>
<span id="cb1-5"><a href="#cb1-5" tabindex="-1"></a> <span class="fu">bindCache</span>(input<span class="sc">$</span>x, input<span class="sc">$</span>y) <span class="sc">%&gt;%</span></span>
<span id="cb1-6"><a href="#cb1-6" tabindex="-1"></a> <span class="fu">bindEvent</span>(input<span class="sc">$</span>go)</span></code></pre><p></p></div>
<p>Anything that consumes <code>r()</code> will take a reactive dependency on the event
expression given to <code>bindEvent()</code>, and not the cache key expression given to
<code><a href="bindCache.html">bindCache()</a></code>. In this case, it is just <code>input$go</code>.</p>
</div>
</div>
<div class="col-md-3 hidden-xs hidden-sm" id="pkgdown-sidebar">
<nav id="toc" data-toggle="toc" class="sticky-top"><h2 data-toc-skip>Contents</h2>
</nav></div>
</div>
<footer><div class="copyright">
<p></p><p>Developed by Winston Chang, Joe Cheng, JJ Allaire, Carson Sievert, Barret Schloerke, Garrick Aden-Buie, Yihui Xie, Jeff Allen, Jonathan McPherson, Alan Dipert, Barbara Borges, Posit Software, PBC.</p>
</div>
<div class="pkgdown">
<p></p><p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.2.0.</p>
</div>
</footer></div>
</body></html>