A reactive read that is TRUE exactly when reading r would return a
value rather than halt or throw: a result has arrived and the last run did
not fail. status_async() alone cannot tell a first run from a refresh,
since both are "running"; combine the two to show a spinner on first load
and a "showing the previous result" note while a new one computes.
Arguments
- r
An object created by
reactiveAsync(),observeAsync()orreactiveValAsync().
Details
Like status_async(), reading it starts a reactiveAsync() that has not
run yet. Inside an async expression it is evaluated on the session thread,
like a reactive read. Use the req() form rather than
if (has_value_async(up)) up() else NA there: every reactive read in an
async expression is a dependency, so the up() in the untaken branch halts
the expression until up has a value and the fallback never shows.
A reactiveValAsync() has a value from the start, its initial one if
nothing else, like shiny::reactiveVal(), unless its last task failed. For
an observeAsync() it is TRUE once a run has succeeded and the last run
did not fail.
Examples
if (interactive()) {
library(shiny)
server <- function(input, output, session) {
forecast <- reactiveAsync(fetch_forecast(input$spot))
output$forecast <- renderTable(forecast())
output$note <- renderUI({
running <- status_async(forecast) == "running"
if (running && !has_value_async(forecast)) {
icon("spinner", class = "fa-spin")
} else if (running) {
span(class = "text-muted", "Showing the previous forecast while the new one loads")
}
})
}
}
