I have a pretty complicated question, and if I need to move it/ change the category please let me know.
I am currently building a shiny dashboard to return results from a survey designed using REDCap. I have built the dashboard, and it communicates (when I run it locally) with the database using the REDCap API and the R package redcapAPI. I am moving towards trying to host this application somewhere (shinyapps.io?) and have a part that I cannot figure out.
Currently, my shiny application connects to the database (successfully!) using the following code snippet
library(redcapAPI)
#establish connection to the API
project <- redcapConnection(url, token)
I then pull the information I want using this function:
#extract only the records from the appropriate subject by variable subject_id into a data frame
data <- exportRecords(project,records = c(subject_id))
Currently, I have to hard code the variable subject_id so that I can change which set of records I am pulling in.
The REDCap program, allows me to redirect a user to a custom URL upon completion of the survey, and I can pipe a variable (subject_id) into the URL. So I could have something like this:
My question is if it is possible to have all of the information needed to launch my application with the appropriate subject ID stored inside of the URL? Are there any tips or resources you can think of that would make this work? Or am I attempting the impossible?
I tested this, and the issue I kept having was with the error message pasted below as well as a message that says "disconnected to server Reload" on the actual page.
Warning: 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.)
[shinyapps]: 65: stop
[shinyapps]: 64: .getReactiveEnvironment()$currentContext
[shinyapps]: 63: getCurrentContext
[shinyapps]: 62: .subset2(x, "impl")$get
[shinyapps]: 61: $.reactivevalues
[shinyapps]: Error in .getReactiveEnvironment()$currentContext() :
[shinyapps]: 59: server [/srv/connect/apps/shiny_004/app.R#76]
[shinyapps]: 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.)
I believe the issue is that I am not treating the information being read in from the session$clientData$url_search as a reactive value.
Pasted below is some of the server code. I wonder if you might suggest how to load this data table in a way that treats the variable as reactive? I have tried assigning it to reactiveValues(), but that has not worked.
server <- function(input, output, session) {
#read the information from the URL
values <- reactiveValues(id = session$clientData$url_search)
#Establish connection to API
project <- redcapConnection(url,
token)#token will be placed here
#export only records associated with the subject Id passed to records
graph_data <- exportRecords(project,records = c(values$id)) %>%
#select only the fields being assessed
select('smell_cosmetics_intensity',
'smell_spice_intensity',
'smell_fruit_intensity',
'smell_other_intensity',
'nasalirritation_intensity',
'taste_bitter_intensity',
'taste_salt_intensity',
'taste_sour_intensity',
'taste_sweet_intensity')
#transmute the table to generate a column for week and the averaged smell and taste values
data <- transmute(graph_data,
week = 0:(nrow(graph_data)-1),
smell = ((smell_cosmetics_intensity + smell_spice_intensity + smell_fruit_intensity + smell_other_intensity) / 4),
smell_2 = nasalirritation_intensity,
taste = ((taste_bitter_intensity + taste_salt_intensity + taste_sour_intensity + taste_sweet_intensity)/4),
taste_2 = nasalirritation_intensity)
#Generate the oral summary graph
output$oral_graph <- renderPlot({
#this is the R code used to generate the Oral graph
oral_graph <- ggplot(data, aes(x = week)) +
geom_line(aes(y = taste), color = "green") +
geom_line(aes(y = taste_2), color = "blue") +
geom_point(aes(x = week, y = taste)) +
geom_point(aes(x = week, y = taste_2)) +
xlab("Time (weeks)") +
ylab("Response to Stimuli") +
theme_classic() +
theme(text = element_text(size = 16))
#return statement
oral_graph
})
To help us help you, could you please prepare a minimal reproducible example (reprex) illustrating your issue? Please have a look at this resources, to see how to create one for a shiny app
Thanks for your help. I tried to create a simple repex, but all examples work fine when i execute them. I am unable to come up with a way to represent the issue as a repex without disclosing the token to my API, as I am quite sure the issue arises from piping the value from session$clientData$url_search into the data frame as illustrated in the code snippet I showed above.
Thank your for your assistance anyway, I will elaborate on the solution if I am able to solve it myself.
I am still having a lot of trouble accomplishing my goals. I have tried to make a simple repex that generates the same error. I have pasted it below. I believe the issue is that I am attempting to load the session$clientData$url_search variable into a datatable in the server function, and it needs to be made "reactive". I do not understand how to accomplish this.
library(shiny)
x_1 <- c(1, 5, 16, 71, 41, 71, 38)
x_2 <- c(12, 23, 88, 74, 62, 63, 34)
y_1 <- c(1, 2, 3, 4, 5, 6, 7)
ui <- fluidPage(
titlePanel("test_1"),
sidebarLayout(
mainPanel(
plotOutput("plot_1")
),
mainPanel(
plotOutput("plot_2")
)
)
)
server <- function(input, output, session) {
# Here you read the URL parameter from session$clientData$url_search
observe({
query <- parseQueryString(session$clientData$url_search)
subject_id <- query[["id"]]
})
data <- data.frame(input$id, x_2, y_1)%>%
select(x_1, y_1)
#Generate the oral summary graph
output$plot_1 <- renderPlot({
#this is the R code used to generate the Oral graph
plot_1 <- ggplot(data, aes(x = input$id)) +
geom_line(aes(y = y_1), color = "green") +
theme_classic() +
theme(text = element_text(size = 16))
#return statement
plot_1
})
}
# Run the application
shinyApp(ui = ui, server = server)
Can you check your reprex? there is no input@id defined in your UI function and you are not using the URL parameter (subject_id) anywhere in your code.
Thank you for catching that. I am struggling to make the repex, as the true version uses code to generate the table from the API. I believe that this version is a better representation.
library(shiny)
x_1 <- c(1, 5, 16, 71, 41, 71, 38)
x_2 <- c(12, 23, 88, 74, 62, 63, 34)
y_1 <- c(1, 2, 3, 4, 5, 6, 7)
ui <- fluidPage(
titlePanel("test_1"),
sidebarLayout(
mainPanel(
plotOutput("plot_1")
),
mainPanel(
plotOutput("plot_2")
)
)
)
server <- function(input, output, session) {
# Here you read the URL parameter from session$clientData$url_search
observe({
query <- parseQueryString(session$clientData$url_search)
subject_id <- query[["id"]]
})
data <- data.frame(x_1, x_2, y_1)%>%
select(input$subject_id, y_1)
#Generate the oral summary graph
output$plot_1 <- renderPlot({
#this is the R code used to generate the Oral graph
plot_1 <- ggplot(data, aes(x = input$subject_id)) +
geom_line(aes(y = y_1), color = "green") +
theme_classic() +
theme(text = element_text(size = 16))
#return statement
plot_1
})
}
# Run the application
shinyApp(ui = ui, server = server)
Check again, you are defining the main panel twice and still referencing an unexisting UI input, subject_id is not a UI input, so you can't reference it that way.
I do not think this repex will be of use then. am not sure if this is more informative, but here is the actual code I am hoping to fix. The issue is line 77 where I attempt to pass subject_id into exportRecords() as an int.