How to access session$user in Shiny using Shiny Pro - r

I have a simple shiny app that I am testing SHINY pro and I would like to access the session$user like the documentation suggests:
http://rstudio.github.io/shiny-server/latest/#flat-file-authentication. See section 4.1 which shows this code:
shinyServer(function(input, output, session) {
output$username <- reactive({
session$user
})
That code works but I need to access session$user in the ui.r file via the GetUser() function
Here is my ui.r File:
library(shiny)
shinyUI(fluidPage(
textOutput("HeaderTime"),
sidebarPanel(
selectInput("t", "t:", as.character(GetUser()), selected = as.character(GetUser())), width = 2
),
mainPanel(
tabsetPanel(
tabPanel("test",
dataTableOutput("Table"),
plotOutput("Plot"),
# verbatimTextOutput("Txt"),
width = 12
)
)
)
))
You can see the GetUser() function in the selectInput. I have placed GetUser() in my server.R file here:
shinyServer(function(input, output, session) {
GetUser<-reactive({
return(session$user)
})
output$Plot<-renderPlot({
hist(rnorm(1000))
})
output$Table<- renderDataTable({
data.frame(a=c(1,2,3,4),b = c("TEst","test","test","test"))
})
})
when I run this code I get the error:
Error in GetUser() : argument "session" is missing, with no default
Any idea how to allow the ui.r to access GetUser() in the server.r file so session$user can be used in the ui?
Here is code to run project:
library(rJava)
library(shiny)
install.packages("shiny")
runApp("C://me/pathtoproject")
Thank you.

The error you get does address the problem (albeit in a cryptic way).
When you call your GetUser function in the ui, the "session" argument is not known (i.e. it is only "known" by the server).
I suggest to use updateSelectInput (or renderUI if you prefer) and send the session$user value from the server side.
Something like (not tested):
server = function(session,input, output) {
GetUser<-reactive({
return(session$user)
})
updateSelectInput(session, "t", "t:", as.character(GetUser()),selected = as.character(GetUser()))

Related

Why do I get an error message when using an observeEvent with this function that works fine when not wrapped in an observer?

The below example code "Code" saves to the browser the user slider input from one session to the next, using package shinyStorePlus. I would like the user to be able to clear the saved inputs via a click of the "clear" actionButton(). When the commented-out code in "Code" is uncommented, revealing the clear function in the server section, clicking that actionButton() results in error Warning: Error in envir$session$sendCustomMessage: attempt to apply non-function. However, if I pull the clear data code of clearStore(appId = appid) out of the observer and run the code this way, it works fine in clearing out the saved browser data. As an example, running the "Isolated Clearing Code" at the very bottom, completely outside the observer, clears out the browser data like it should.
What am I doing wrong here with my use of an observer? I've fooled around with using isolate(), making the appid reactive, etc., and nothing seems to work.
Code:
library(shiny)
library(shinyStorePlus)
ui <- fluidPage(
initStore(), br(),
sliderInput("input1",label=NULL,min=1,max=200,value=100),
actionButton("clear","Clear data")
)
server <- function(input, output, session) {
appid <- "application001"
setupStorage(
appId = appid,
inputs = list("input1")
)
# observeEvent(input$clear,{
# clearStore(appId = appid)
# })
}
shinyApp(ui, server)
Isolated Clearing Code:
ui <- fluidPage(
initStore(),
)
server <- function(input, output, session) {
appid <- "application001"
clearStore(appId = appid)
}
shinyApp(ui, server)
This seems to be an issue with shinyStorePlus' code:
> clearStore
function (appId)
{
envir <- parent.frame()
envir$session$sendCustomMessage("clearStorage", appId)
}
using parent.frame() to get the session is unfavorable.
Please check the following instead:
library(shiny)
library(shinyStorePlus)
clearStore <- function(appId, session = getDefaultReactiveDomain()){
session$sendCustomMessage("clearStorage", appId)
}
ui <- fluidPage(
initStore(), br(),
sliderInput("input1",label=NULL,min=1,max=200,value=100),
actionButton("clear","Clear data")
)
server <- function(input, output, session) {
appid <- "application001"
setupStorage(
appId = appid,
inputs = list("input1")
)
observeEvent(input$clear,{
clearStore(appId = appid)
})
}
shinyApp(ui, server)
I left a PR here.

How to pass a calculated file name back to the UI in Shiny

In my shiny server I am figuring out the name of a markdown file which I want to show in the UI. I know how to pass the file name, as a string, back to the UI but I don't now how to tell includeMarkdown() to treat the string as a file name.
My code so far is below. Any advice?
library(shiny)
fileConn<-file("hello.md")
writeLines(c("# Hello","# World"), fileConn)
close(fileConn)
ui <- fluidPage(
includeMarkdown("hello.md"),
br(),
div("File name text:", textOutput("fileNameText", inline = TRUE)),
#includeMarkdown(fileNameText) # this needs help
)
server <- function(input, output, session) {
selectedName <- reactive({
paste0("hello.md") # this is actually more complicated...
})
output$fileNameText <- renderText(
paste0(selectedName())
)
}
shinyApp(ui = ui, server = server)
Your example code works fine, but from your description, I am thinking your asking how to pass a different filename to includeMarkdown() that was created somewhere else in the app, correct?
The first step is to understand includeMarkdown() as a UI element that will change depending on other UI elements (and stuff that happens in server). The solution is to use a placeholder in the ui to hold the place for the includeMarkdown() element, and create that particular element in server using renderUI.
Hopefully you can follow this example. I'm using uiOutput('displayFile') to hold the place for the element that's created in server.
library(shiny)
fileConn<-file("hello.md")
writeLines(c("# Hello","# World"), fileConn)
close(fileConn)
fileConn1<-file("goodbye.md")
writeLines(c("# Goodbye","# Everyone!"), fileConn1)
close(fileConn1)
ui <- fluidPage(
selectInput('file_selection', 'Choose Markdown File:', choices=c('hello.md','goodbye.md')),
uiOutput('displayFile')
)
server <- function(input, output, session) {
output$displayFile <- renderUI({
includeMarkdown(input$file_selection)
})
}
shinyApp(ui = ui, server = server)

How to use sjPlot to report a html table in R shiny?

Why can't my code run successfully? How do I use sjPlot to create a html table in shiny?
library(shiny)
library(sjPlot)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(),
mainPanel(htmlOutput("a"))
)
)
server <- function(input, output){
output$a <- renderUI({
tab_df(iris,title="title",col.header='N',footnote='footnote')
})
}
# Run the application
shinyApp(ui = ui, server = server)
When I run the code , the log is "Warning: Error in if: argument is of length zero". I don't know what's wrong with the code.
Thanks.
The problem is that tab_df seems to write its HTML out to a file rather than return the HTML that you want to use. Looking at the sjPlot:::print.sjTable, it seems like we can get around that with
server <- function(input, output){
output$a <- renderUI({
HTML(tab_df(iris,title="title",col.header='N',footnote='footnote')$knitr)
})
}

How to refer to reactive element in ui.R in Shiny

I am making an app with drag and drop feature using the ShinyDND package. I would like to pass a list from input as a parameter of dragSetUI, a function that needs to be run in ui.R. I tried renderUI and uiOutput, and it almost works, but the dragged elements fail to be dropped in the drop area. As you can see in the example below, nonreactive choices work like charm. I tried creating a reactive object as well as text output, but I could not find documentation on how to refer to these objects in ui.R. Normally one would refer to output$x as "x" in Output, but here, if I add anything between quotes, it reads as string. I am really stuck with this.
library(shiny)
library(shinyDND)
nonreactive_choices<-as.list(c("a","b","c"))
ui <- shinyUI(
mainPanel(
textInput("choices","Put here a,b,c:"),
dragSetUI("drag", textval = "reactive_choices"),
dragSetUI("drag", textval = "choice_rv"),
textOutput("reactive_choices"),
dragSetUI("drag", textval = nonreactive_choices),
dropUI("drop")
)
)
server = shinyServer(function(input, output,session) {
output$reactive_choices<-reactive({
strsplit(input$choices,",")
})
observe({
chlist<-strsplit(input$choices,",")
choice_rv<-reactiveVal(chlist)
})
})
# Run the application
shinyApp(ui = ui, server = server)
Let's see why the renderUI approach does not work with shinyDND. An app using shinyDND is linked to the dragndrop.js file, which is in the shinyDND folder. In this file one can see:
$(document).ready(function(){
......
$(".dragelement").on("dragstart",function(e){
e.originalEvent.dataTransfer.setData("Text",e.target.id);
});
......
});
This defines the action to perform on elements having class dragelement when a drag is starting, and this is defined when the document is ready. dragSetUI creates such elements.
When you use a dragSetUI inside a renderUI, this creates new elements of class dragelement. But the action defined on such elements in $(document).ready is not effective for these new elements, because this action has been defined just after the document is ready, and then before the effect of renderUI.
A solution consists in defining the action of the event dragstart inside the renderUI. This works:
library(shiny)
library(shinyDND)
nonreactive_choices<-as.list(c("a","b","c"))
ui <- shinyUI(
mainPanel(
textInput("choices","Put here d,e,f:"),
dragSetUI("drag", textval = nonreactive_choices),
uiOutput("dragset"),
dropUI("drop")
)
)
server = shinyServer(function(input, output,session) {
reactive_choices <- reactive({
strsplit(input$choices,",")[[1]]
})
output$dragset <- renderUI({
tagList(
dragSetUI("drag2", textval = as.list(reactive_choices())),
tags$script('$(".dragelement").on("dragstart",function(e){
e.originalEvent.dataTransfer.setData("Text",e.target.id);
});'
)
)
})
})
# Run the application
shinyApp(ui = ui, server = server)
Comment by #ismirsehregal helped me find the solution: shinyjqui can be used for my purposes and it seems to work from inside renderUI. Here is the edited code that does exactly what I needed.
library(shiny)
library(shinyjqui)
ui <- fluidPage(
textInput("choices","Put here a,b,c:"),
uiOutput("reactiveselect"),
orderInput(inputId = 'drop', label = 'Reactive drop', items = NULL,placeholder = "drop here..."),
verbatimTextOutput("droppedorder")
)
server <- function(input, output) {
output$reactiveselect <- renderUI({
req(input$choices)
reactiveitems<- unlist(strsplit(input$choices,","))
orderInput("groupstochoose", "groups to choose from:", connect='drop',items=reactiveitems)
})
output$droppedorder<-
renderPrint({input$drop_order})
}
shinyApp(ui, server)

How do I print an input from the R shiny UI to the console?

Situation: I want to print an input variable from the R shiny UI to the console. Here is my code:
library(shiny)
ui=fluidPage(
selectInput('selecter', "Choose ONE Item", choices = c("small","big"))
)
server=function(input,output,session){
print("You have chosen:")
print(input$selecter)
}
shinyApp(ui, server)
Unfortunately I get this error message:
Error 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.)
Question: What do I need to change my code to, in order to make it work?
You should use an observeEvent which will execute every time the input changes:
library("shiny")
ui <- fluidPage(
selectInput('selecter', "Choose ONE Item", choices = c("small","big")),
verbatimTextOutput("value")
)
server <- function(input, output, session){
observeEvent(input$selecter, {
print(paste0("You have chosen: ", input$selecter))
})
}
shinyApp(ui, server)

Resources