Skip to contents

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.

Usage

has_value_async(r)

Arguments

r

An object created by reactiveAsync(), observeAsync() or reactiveValAsync().

Value

TRUE or FALSE.

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")
      }
    })
  }
}