Reputation: 3760
I am having a problem with eventReactive
in ShinyApp
. I would like the user at the beginning to write user name and password click the actionButton
and get a message "sucessfull connection". I managed to do it without any problems, however when i wanna use the con
as for example to get list of the tables using dbListTables
, it says that: Error: object 'con' has not been found
, while using the reactive object connectDB()
i get an error: Fehler bei der Auswertung des Argumentes 'conn' bei der Methodenauswahl
für Funktion 'dbListTables': Fehler in .getReactiveEnvironment()$currentContext() :
Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
How can i get the connection working?
My code:
library(ROracle)
library(shiny)
library(DT)
server <- shinyServer(
function(input, output, session) {
connectDB <- eventReactive(input$connectDB, {
if(input$drv != "Oracle"){
stop("Only 'Oracle' implemented currently")
}else{
drv <- dbDriver("Oracle")
}
con <- dbConnect(drv,"xx/K",username=input$user,password=input$passwd)
con
})
output$test <- renderText({
con <- connectDB()
"connection success"
})
tableList <- dbListTables(con,schema="K") #I have tried here to use con and as well reactive object in form of connectDB()
output$out <- renderPrint(tableList)
updateSelectizeInput(session, "tabnames", server = TRUE, choices = tableList)
sqlOutput <- reactive({
sqlInput <- paste("select * from K.",input$tabnames)
dbGetQuery(con, sqlInput)
})
output$table <- DT::renderDataTable(sqlOutput(), server=TRUE, rownames=FALSE, filter="top", options=list(pageLength=10))
session$onSessionEnded(function() { dbDisconnect(con) })
})
ui_panel <-
tabPanel("Test",
sidebarLayout(
sidebarPanel(sidebarPanel(
textInput("drv", "Database Driver", value="Oracle"),
textInput("user", "User ID"),
passwordInput("passwd", "Password"),
actionButton("connectDB", "Connect to DB"))
),
mainPanel(
textOutput("test"),
selectizeInput("tabnames",label = "server side", choices = NULL),
tableOutput("out"),
dataTableOutput("table")
)
)
)
ui <- shinyUI(navbarPage("Test",ui_panel))
runApp(list(ui=ui,server=server))
Thanks for any help!
Upvotes: 1
Views: 1782
Reputation: 7871
Here only part of what you have to do
UI
library(shiny)
shinyUI(navbarPage("Test",
tabPanel("Test",
sidebarLayout(
sidebarPanel(
textInput("drv", "Database Driver", value="Oracle"),
textInput("user", "User ID"),
passwordInput("passwd", "Password"),
actionButton("connectDB", "Connect to DB")) ,
mainPanel(
textOutput("test"),
uiOutput("tabnames_ui"),
tableOutput("out"),
dataTableOutput("table")
))
)
))
Server
library(ROracle)
library(shiny)
shinyServer(function(input, output, session) {
con=reactiveValues(cc=NULL)
observeEvent(input$connectDB,{
if(input$drv != "Oracle"){
con$cc="Only 'Oracle' implemented currently"
}else{
drv <- dbDriver("Oracle")
con$cc<- dbConnect(drv,"xx/K",username=input$user,password=input$passwd)
}
})
observe({
if(!is.null(con$cc)& is(con$cc,"OraConnection")){ # check if connected
output$test <- renderText({
"connection success"
})
tableList <-reactive({
dbListTables(con$cc,schema="K")
})
output$out <- renderPrint(tableList())
output$tabnames_ui=renderUI({selectInput("tabnames",label = "server side", choices = tableList())})
}else if (!is.null(con$cc) ){
output$test <- renderText({
con$cc
})
}
})
session$onSessionEnded(function() {
observe({
if(!is.null(con$cc)& is(con$cc,"OraConnection")){# check if connected
print(paste0("disconnect ",dbDisconnect(con$cc)))}
})
})
})
Upvotes: 2