I am using renderUI to create a "DisplayName" input and I have a reactive function called "ReactiveTest" that uses input$DisplayName. If you run the code below you will see that the "DisplayName" drop down list calls the NameAndID() which in turn calls GetDisplayName() in the global.r file. That call populates the "DisplayName" dropdown list.
BUT when ReactiveTest() tries to access input$DisplayName it says that input$DisplayName is NULL then there seems to be a second call to ReactiveTest() and THEN it sees the input$DisplayName
so when you run the code you will see the timing looks like this:
[1] "Department dropdown list is being returned now"
[1] "Department dropdown list is being returned now"
Listening on http://155.0.0.1:555
[1] "DISPLAY NAME dropdown list is being returned now"
[1] "Now ReactiveTest() tries to access input$DisplayName"
[1] "ReactiveTest() says input$DisplayName Name is NULL" --> why is it NULL? if 2 lines above the dropdown was populated???
[1] "Now ReactiveTest() tries to access input$DisplayName"--> Where is this coming from? Shouldn't there only be 1 call to ReactiveTest()
[1] "ReactiveTest() says input$DisplayName Name is Bob"
I have 3 questions:
(1) Why does ReactiveTest() not see the input$DisplayName after the DisplayName dropdown is called?
(2) Why is there a second call to ReactiveTest()?
(3) How can I make ReactiveTest() see whats in the "DisplayName" dropdown the first call? In my real code I have to test for is.null(input$DisplayName)== TRUE and then not run some code but isn't there a better way?
Here is my code which you can run:
library(shiny)
runApp(list(
ui = basicPage(
sidebarPanel(
selectInput("Department", "Select a department",
choices = as.character(GetDepartments()$Department),
selected = as.character(GetDepartments()$Department[1])),
uiOutput("DisplayName")
),
mainPanel(textOutput("Text") )
),
server = function(input, output, session) {
NameAndID<- reactive({
GetDisplayName(input$Department)
})
output$DisplayName<-renderUI({
Department <- input$Department
selectInput("DisplayName", 'DisplayName:', choices = as.character(NameAndID()$DisplayName), selected =as.character(NameAndID()$DisplayName[1] ))
})
ReactiveTest<- reactive({
print("Now ReactiveTest() tries to access input$DisplayName")
if(is.null(input$DisplayName) == TRUE)
{
print("ReactiveTest() says input$DisplayName Name is NULL")
return("NULL")
}else
{
print(paste0("ReactiveTest() says input$DisplayName Name is ", input$DisplayName))
return(input$DisplayName)
}
})
output$Text <- renderText({
#myData <- GetDisplayName(input$Department)
#code <- as.character(myData[myData$DisplayName == input$DisplayName,2])
return(ReactiveTest())
})
}
))
global.r
GetDepartments<- function(){
df<- data.frame(Department= c("Dept A", "Dept B"), id = c(1,2))
print("Department dropdown list is being returned now")
return(df)
}
GetDisplayName<- function(Dept){
if(Dept == "Dept A")
{
df<- data.frame(DisplayName= c("Bob", "Fred"), id = c(4,6))
print("DISPLAY NAME dropdown list is being returned now")
return(df)
}else
{
df<- data.frame(DisplayName= c("George", "Mary"), id = c(10,20))
print("DISPLAY NAME dropdown list is being returned now")
return(df)
}
}