H!
I am trying to do conditional caching for a shiny app.
Let's suppose that a script for the shiny app occasionally will result in an error that will resolve later in time. If I immediately cache the first-run-results, the resulting solution will not be re-ran as the server logic will first go to the cached version which is problematic if the first run resulted in an error.
Thus, I would like to implement some logic flow allowing for conditional caching.
Yet, it doesn't work and I can't figure out why.
Reproducible Example using moduleServer
library(ggplot2)
library(dplyr)
shinyOptions(cache = cachem::cache_disk("myapp-cache"))
ui <- fluidPage(
mainPanel(
textInput(inputId = "test",
label = "test input",
value = "yup"),
plotOutput(outputId = 'test_plot')
)
)
##
server <- function(input, output, session){
reactive({input$test}) -> key
server.create_graph(id = 'test_plot') -> output$test_plot
}
shiny::shinyApp(ui, server)
Second Script:
server.create_graph <- function(id){
moduleServer(
id,
function(input, output, session){
renderPlot({
## Create random data
rep(c('a', 'b'), 5) -> error.data
c(1:10) -> correct.data
data.frame('error_data' = error.data,
'correct_data' = correct.data,
'values' = 1:10) -> test.df
## Create Plot with randomly chosen
sample(x = c(1, 2), size = 1) -> random.choice
test.df[, c(random.choice, 3)] -> graph.df
ggplot(data = graph.df) +
geom_line(aes(x = graph.df[, 1], y = graph.df[, 1] - graph.df[, 2])) -> graph.object
return(graph.object)
}) %>% bindCache(., input$key)
}
)
}
This will appropriately cache all outputs, even if it is the error and not the graph.
But suppose I want to ensure that the output of a graph, and not an error. So I write a function to do just that and then I add it like so:
server.create_graph <- function(id){
moduleServer(
id,
function(input, output, session){
renderPlot({
## Create random data
rep(c('a', 'b'), 5) -> error.data
c(1:10) -> correct.data
data.frame('error_data' = error.data,
'correct_data' = correct.data,
'values' = 1:10) -> test.df
## Create Plot with randomly chosen
sample(x = c(1, 2), size = 1) -> random.choice
test.df[, c(random.choice, 3)] -> graph.df
ggplot(data = graph.df) +
geom_line(aes(x = graph.df[, 1], y = graph.df[, 1] - graph.df[, 2])) -> graph.object
return(graph.object)
}) %>% checkBefore(., input$key) ## New checking function
}
)
}
## Function checks if item is a ggplot class before caching
checkBefore <- function(item, input){
if('ggplot' %in% class(item)){
bindCache(item, input)
}
return(item)
}
Even when the item is a ggplot, nothing gets cached.
Ideas?