I have a very large application with many actionButtons triggering events. I use the following logic for all my actionButtons in server.R:
observe({
if(input$myButton==0) return(NULL)
isolate({
# Code goes here
})
})
At some stage recently, the code within the isolate({}) now triggers twice whenever I click the actionButton.
It happens on all buttons within my project - and I can't think of how to debug it. Can anyone offer advice on debugging or what to look for?
For debugging purposes you could use reactive log visualizer and showcase mode:
Start with a fresh R session and run the command options(shiny.reactlog=TRUE)
Then run your app in a show case mode: runApp("yourApp", display.mode = "showcase")
At any time you can hit Ctrl+F3 (or for Mac users, Command+F3) in your web browser to launch the reactive log visualization.
Related
I have the below function to read data from RDS file.
# Function to get updated data
updateData <- function(forceclick = FALSE){
update_data <<- readRDS(path, "update_data.rds")
}
And, there is an action button in the UI to update data when it is triggered.
##On the UI side action button to refresh data load
actionButton("update_button",
"Data refresh")
###data refresh code on server side
observeEvent(input$update_button, {
updateData(forceclick = TRUE)
})
Here the data is refreshed when the actionButton ´input$update_button´ is triggered.
Here i am supposed to do manual refresh using the action button as shown in the sample code or manually scale down the pods and scale up.
How could the data upload be automated for eg: every morning without the need to trigger the actionButton ´input$update_button´?
Can ´invalidateLater´ be used for observeEvent like below?
###data refresh code on server side
observeEvent(input$update_button, {
invalidateLater(1000000,session)
updateData(forceclick = FALSE)
})
or could it be solved if the updateData() is executed periodically at set time which reads the .rds file?
Background
I am currently building a „Data-Logger“ - App using R Shiny. I do have an REST - API, which returns a value, that changes over time. My goal is to create an Shiny App, in which an user can click on an actionbutton to start writing the values fetched from the api periodically (e.g. every 60 seconds) to a dataframe. The logging of the data also should be stopped, when the user clicks on another actionbutton.
Problem
My problem is writing a function that starts executing when a button is pressed, executes periodically after that and stops executing when another button is pressed.
Previous Ideas
I previously tried using invalidateLater(), but i could not achieve what i desire.
Can you guys help me out with a clever thought or idea?
Thanks in advance!
This should show how it works. invalidateLater() is the right choice. The start/stop buttons change a reactive expression that determines whether polling is on or off. That way, the reactive RestPoll expression gets notified every time it gets switched on/off and, of course, after 500 ms as long as Running() == TRUE.
library(shiny)
ui <- fluidPage(
actionButton("btnStart", "Start"),
actionButton("btnStop", "Stop"),
textOutput("outTime")
)
server <- function(input, output, session) {
Running <- reactiveVal(FALSE)
observeEvent(input$btnStart, {
Running(TRUE)
})
observeEvent(input$btnStop, {
Running(FALSE)
})
RestPoll <- reactive({
if (Running()) # IS called every time `Running` changes
invalidateLater(500, session)
# Add any REST calls here, process the results
return(Sys.time()) # deliver results
})
output$outTime <- renderText({
req(RestPoll())
})
}
shinyApp(ui, server)
You could also do it with a reactiveTimer but that would also poll and use resources when polling is not required.
I have a shiny app with many inputs & a scoring function. There is no action button per se. Any input change triggers a re-score.
Sometimes a user has changed the input but it takes the score some time to update. This may mislead the user in associating the new state with the old score.
I want to fix this by having some display cue e.g. a "Score is being computed" message or gray out UI etc. dynamically whenever the score shown is stale.
How do I achieve this? Any thoughts?
fn_run<-reactive({
scorer(inputs......)
})
output$score<-renderPrint(cat(fn_run()$score))
sidebarPanel(title="Scoring Outputs",width = 3,
h3(textOutput("title")),
h3(textOutput("score"),style="color:blue"),
)
Mostly the delay is discernible when I publish the app to shinyapps.io and not palpable on local shiny runs.
You can do this with some CSS and the shinyjs package.
The following blog has what I think you want:
http://deanattali.com/blog/advanced-shiny-tips/
The relevant code is found here:
https://github.com/daattali/advanced-shiny/blob/master/loading-screen/app.R
This will show you how to shade the whole screen whilst the app is loading.
I am developing a R Shiny application involving Twitter data fetching. As the process could last some time I would like to indicate that the application is busy doing something, so the user doesn't thing the page is frozen.
In my case, I store some reactive values this way:
rv <- reactiveValues()
rv$analysisStarted <- FALSE
rv$analysisAvailable <- FALSE
Then, in UI, the user must press an actionButton in order to start processing. Then, I would like to indicate somewhere the Server is working...
observeEvent(input$analysisButton, {
rv$analysisStarted <- TRUE
rv$analysisAvailable <- FALSE
#Processing Twitter info...
rv$followersAnalysisStarted <- FALSE
rv$followersAnalysisAvailable <- TRUE
})
If, in UI.r, I place a textOutput and create the corresponding output method this way, it does NOT work:
output$text <- renderText({
if (rv$analysisStarted) {
"Server is working..."
} else if (rv$analysisAvailable) {
"Your report is ready :) "
} else {
"Enter the data to search and press analysisButton"
}
})
What I have noticed is when the analysis begins, the label changes to a gray color, but it doesn't update the text until the process is over.
What should be the proper coding of this feature?
Is it possible to redraw the text output within observeEvent?
Is it possible with the raw shiny library or requires shinyjs, which I am also using?
Any help would be grateful.
In your case, it would be helpful a progressbar to check the state. This element would be appreciate by your users to indicate the state. Unfortunately, the progress bar would have to code before the functionality. It is a trick, you see a progress bar but this object stops when the function starts.
Here is the tutorial: http://shiny.rstudio.com/gallery/progress-bar-example.html
From my point of view, the progress bar is the best way to inform the web users of the website state but it is not completely perfect. Further you can change the style of the bar with CSS to customize and select your own colors, size...
I want to be able to click a button within my Shiny App. So far so easy.
But when doing so, a function that loads, writes and then saves an excel sheet should be executed "behind the scenes" with no output changed in the App itself.
How can I do this?
Kind regards,
Martin
Yes. Try to use an Observer.
in server.R:
shinyServer(function(input, output, session) {
# other code ...
observe({
# do_something_button is your actionButton id.
if (input$do_something_button > 0) {
# perform behind the scenes analysis here.
# if you want to send a message to the client side, you can try
# something like:
message <- list(type="completed", excel_file=saved_file)
session$sendCustomMesage("background_task", message)
}
})
# other code ...
})
then write some custom javascript snippet and load it via ui.R:
Shiny.addCustomMessageHandler("background_task", function(message) {
console.log("Finished processing: " + message.excel_file);
});
In this way when the server completes the background processing, or should an error occur, you can get some feedback on the client side. Maybe you want to notify the user about an error or something.
The reference for using observe is here