Restart Shiny Session

Restart Shiny Session

You can use the history.go(0) js-method to reload the page and thus reset the session, e.g. from a link:

p(HTML("<A HREF=\"javascript:history.go(0)\">Reset this page</A>"))

Furthermore you can use the shinyjs package to execute javascript from within the server:

library(shiny)
library(shinyjs)

jsResetCode <- "shinyjs.reset = function() {history.go(0)}" # Define the js method that resets the page

shinyApp(
ui = fluidPage(
useShinyjs(), # Include shinyjs in the UI
extendShinyjs(text = jsResetCode, functions = "reset"), # Add the js code to the page
actionButton("reset_button", "Reset Page")
),

server = function(input, output) {
observeEvent(input$reset_button, {js$reset()}) # Call the method from
# somewhere within the server
})

Restart shiny app from within app (reloading data)

To reload the csv file you need to place reading of the file inside the server.

server <- function(input, output, session){

#Read the data inside the server!!!
data <- read.csv2("data.csv")# this should get executed whenever js$reset is called

output$map <- renderLeaflet({
leaflet(data) %>% addTiles() %>%
setView(11.5, 48, 7) %>%
addDrawToolbar() %>%
addMarkers()
})

data_reactive <- reactiveValues(new_data = data)

# add new point to existing data and save data as data.csv
# after that the app should restart
observeEvent(input$map_draw_new_feature, {
# browser()
data_reactive$new_data <- rbind(rep(NA, ncol(data)), data_reactive$new_data)
data_reactive$new_data$longitude[1] <- input$map_draw_new_feature$geometry$coordinates[[1]]
data_reactive$new_data$latitude[1] <- input$map_draw_new_feature$geometry$coordinates[[2]]
write.csv2(data_reactive$new_data, "data.csv", row.names = FALSE)
js$reset() # this should restart the app
})
}

R Shiny - Refresh app session (shinyjs.reset) when navigating to a specific navbarPage tab

The problem here is that input$p1 doesn't exist. To find out when a tab is clicked and what tab is clicked, you need to give an id to the tab container, and use that id as the input. Also, you mention you want a reset, but the code you're using is a very hard reset - it refreshes the page, it's literally the equivalent of pressing the Refresh button. I don't quite understand how the logic you want would work (every time you click on tab 2, the app refreshes and you're back at tab 1 - that means you can never get to tab 2!), but anyway here's what it would look like:

library(shiny)
library(shinyjs)

#### Specify the number of pages to use
NUM_PAGES <- 2

# Define the js method that resets the page
jsResetCode <- "shinyjs.reset = function() {history.go(0)}"

# UI
ui <- navbarPage(
id = "mytabs",

# Call shinyjs
useShinyjs(),
extendShinyjs(text = jsResetCode, functions = "reset"),

### Panel 1 ###
tabPanel(id = "p1",
title = "A",
"Page 1"),

### Panel 2 ###
tabPanel(id = "p2",
title = "B",
div(id = "form",

### Sub-panel 1
conditionalPanel(
condition = "input.nextBtn_1 == 0",
radioButtons(inputId ="Q1", ("Q1"), choices = c("A", "B"),
selected = character(0)),

# Next page button
div(actionButton("nextBtn_1", "Next1 >"))),

### Sub-panel 1
conditionalPanel(
# Q1
condition = "input.nextBtn_1 == 1 && input.nextBtn_2 == 0",
radioButtons(inputId ="Q2", ("Q2"),
choices = c("A", "B" , "C"),
selected = character(0)),
# Q2
radioButtons(inputId ="Q3", ("Q3"),
choices = c("A", "B"),
selected = character(0)),

# Next page button
div(actionButton("nextBtn_2", "Next2 >")))
)))

# Server
server <- function(input, output) {

# Observe event
observeEvent(input$mytabs, {
if (input$mytabs == "A") {
print("tab 1 clicked")
}
if (input$mytabs == "B") {
print("refreshing page")
js$reset()
}
})

# The function for adding the page value
navPage <- function(input, direction) {
input <- input + direction
}

# When nextBtn is pressed, one is added to page number
observeEvent(input$nextBtn_1, navPage(input$nextBtn_1, 1))# navPage(1)
observeEvent(input$nextBtn_2, navPage(input$nextBtn_2, 1))# navPage(1)

}

# run
shinyApp(server = server, ui = ui)

Refreshing a R shiny session from within the server part

I will have to see a complete code to be able to help you. See if these will help you. Have fun

library(shiny)
library(shinydashboard)

dat = data.frame(id = c("d","a","c","b"), a = c(1,2,3,4), b = c(6,7,8,9))

header <- dashboardHeader(

)

sidebar <- dashboardSidebar(
tags$head(tags$style(HTML('.content-wrapper { height: 1500px !important;}'))),
sidebarMenu (
menuItem("A", tabName = "d1"),
menuItem("B", tabName = "d2"),
menuItem("C", tabName = "d3")
)
)

body <- dashboardBody(

tabItems(
tabItem(tabName = "d1",
box(title = "AAA",
actionButton("refreshTab1_id", "Refresh Tab 1"),
actionButton("sortTable1_id", "Sort Table 1"),
DT::dataTableOutput("table_for_tab_1", width = "100%"))
),
tabItem(tabName = "d2",
box(title = "BBB",
actionButton("refreshTab2_id", "Refresh Tab 2"),
actionButton("sortTable2_id", "Sort Table 2"),
DT::dataTableOutput("table_for_tab_2", width = "100%"))
),
tabItem(tabName = "d3",
box(title = "CCC",
actionButton("refreshTab3_id", "Refresh Tab 3"),
actionButton("sortTable3_id", "Sort Table 3"),
DT::dataTableOutput("table_for_tab_3", width = "100%"))
)
)
)

# UI
ui <- dashboardPage(header, sidebar, body)

# Server
server <- function(input, output, session) {

observe({

if (input$sortTable1_id || input$sortTable2_id || input$sortTable3_id) {
dat_1 = dat %>% dplyr::arrange(id)
} else {
dat_1 = dat
}

output$table_for_tab_1 <- output$table_for_tab_2 <- output$table_for_tab_3 <- DT::renderDataTable({

DT::datatable(dat_1,
filter = 'bottom',
selection = "single",
colnames = c("Id", "A", "B"),
options = list(pageLength = 10,
autoWidth = TRUE#,
# columnDefs = list(list(targets = 9,
# visible = FALSE))
)
)
})
})

observe({
if (input$refreshTab1_id || input$refreshTab2_id || input$refreshTab3_id) {
session$reload()
}
})

}

# Shiny dashboard
shiny::shinyApp(ui, server)

Immediately seeing changes in R shiny UI, in the browser, after making changes in code without having to restart the server?

You could use reactiveFileReader to regularly source the code you'd save in another file, and renderUI()/uiOutput to display that dynamic UI:

app.R

library(shiny)

ui <- uiOutput("ui")

server <- function(input, output, session) {
ui <- reactiveFileReader(1000, session, "source.R", source)
output$ui <- renderUI(ui())
}

shinyApp(ui = ui, server = server)

source.R

fluidPage(
textInput("text", "text"),
textInput("text2", "text")
)

You still have to find out howto get rid of that "TRUE":
result

How do I make a Shiny reset button that resets input values then updates data?

actionButton() function has an internal value that increments by 1 each time it is pressed. For resetting the app, i can think of using session$reload() if there are no other tabs you need to conserve. If only a portion of the ui needs to reset, then you can call renderUI inside observeEvent.

Finally, for the update button we can use the input values but isolate them so the only thing that triggers an update is clicking the button and not changing in this case the slider.

library(shiny)

tab1_ui <- tagList(
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30),
actionButton('reset', 'RESET'),
actionButton("update","UPDATE"),
),
mainPanel(
plotOutput("distPlot")
) )
)

ui <- navbarPage(
title = "Old Faithful Geyser Data",
tabPanel('Tab 1',
uiOutput('tab_1_ui')),
tabPanel('Tab 2',
selectInput('iris_nms', 'Select Column', names(iris)))
)

server <- function(input, output,session) {

#show the ui at the start of the app.
output$tab_1_ui <- renderUI({
tab1_ui
})

# When reset button is pressed, reset the slider value and send a 'push update' signal
observeEvent(input$reset,{
output$tab_1_ui <- renderUI({
tab1_ui
})
})

# When update button is pressed, send a 'push update' signal
observe({
input$update
input$reset
output$distPlot <- renderPlot({
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = isolate(input$bins[1]))
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})

})


}

shinyApp(ui = ui, server = server)

How does one terminate all processes upon Shiny app end?

@PorkChop's comment is pointing in the right direction. However, I'd recommend using processx::process rather than run as it provides us with methods to control the started process from within R. See ?process. (run by the way is also based on the process class.)

The main problem here is, that running the process synchronously (wait=TRUE) blocks the R session. Accordingly onStop won't fire until R is back in control.
Therefore you can't trigger anything once the browser window was closed because the shiny-session continues to run until the external program is finished and R can close the shiny-session.

On session end, the below code checks if the asynchronously started process is still alive and kills it if necessary (tested on windows only).

library(shiny)
library(processx)

ui <- fluidPage(
actionButton("runBtn", label="Run a program that consumes many resources"),
actionButton("stopSession", "Stop session")
)

server <- function(input, output, session) {

myProcess <- NULL

observeEvent(input$stopSession, {
cat(sprintf("Closing session %s\n", session$token))
session$close()
})

observeEvent(input$runBtn,
{
if(Sys.info()[["sysname"]]=="Windows"){
writeLines(text = c("ping 127.0.0.1 -n 60 > nul"), con = "sleep.bat")
myProcess <<- process$new("cmd.exe", c("/c", "call", "sleep.bat"), supervise = TRUE, stdout = "")
} else {
myProcess <<- process$new("sleep", "60", supervise = TRUE, stdout = "")
}
# myProcess$wait() # wait for the process to finish
})

onStop(function(){
cat(sprintf("Session %s was closed\n", session$token))
if(!is.null(myProcess)){
if(myProcess$is_alive()){
myProcess$kill()
}
}

})
}

shinyApp(ui, server)

Regarding the different session callback functions see this related post.


As requested here the process is wrapped in a reactiveVal:

library(shiny)
library(processx)

ui <- fluidPage(
actionButton("runBtn", label="Run a program that consumes many resources"),
actionButton("stopSession", "Stop session")
)

server <- function(input, output, session) {

myProcess <- reactiveVal(NULL)

observeEvent(input$stopSession, {
cat(sprintf("Closing session %s\n", session$token))
session$close()
})

observeEvent(input$runBtn,
{
if(Sys.info()[["sysname"]]=="Windows"){
writeLines(text = c("ping 127.0.0.1 -n 60 > nul"), con = "sleep.bat")
myProcess(process$new("cmd.exe", c("/c", "call", "sleep.bat"), supervise = TRUE, stdout = ""))
} else {
myProcess(process$new("sleep", "60", supervise = TRUE, stdout = ""))
}
# myProcess()$wait() # wait for the process to finish
})

onStop(function(){
cat(sprintf("Session %s was closed\n", session$token))
if(!is.null(isolate(myProcess()))){
if(isolate(myProcess()$is_alive())){
isolate(myProcess()$kill())
}
}

})
}

shinyApp(ui, server)


Related Topics



Leave a reply



Submit