Search code examples
shiny-serverrmongodbshiny

Pass shiny UI text input into rmongodb query


Below is a simplified version of my code. I'm simply trying to get Shiny to pass an input value to an rmongodb query, run the query based on the user input, and then plot the mean of a variable. The code below includes everything needed to replicate my issue, including insertion of documents into the collection.

I'd be very grateful for any help! I'm pulling my hair out (and there wasn't much left to begin with). I suspect that I'm placing the reactive() command inappropriately or something along those lines.

Many thanks to whoever can provide assistance.

#Install required packages and call each
library(devtools)
install_github(repo = "mongosoup/rmongodb")
library(rmongodb)
library(shiny)

#Establish connection with mongodb, check status, name database and collection, insert some documents, return one document
mongo <- mongo.create()

mongo.insert(mongo, "simpledb.main",'{"user":"Joe", "age":34}')
mongo.insert(mongo, "simpledb.main",'{"user":"Joe", "age":31}')
mongo.insert(mongo, "simpledb.main",'{"user":"Joe", "age":53}')
mongo.insert(mongo, "simpledb.main",'{"user":"Kate", "age":29}')
mongo.insert(mongo, "simpledb.main",'{"user":"Lisa", "age":21}')
mongo.insert(mongo, "simpledb.main",'{"user":"Henry", "age":34}')
mongo.insert(mongo, "simpledb.main",'{"user":"David", "age":43}')

if(mongo.is.connected(mongo) == TRUE) {
  help("mongo.count")
  mongo.count(mongo, "simpledb.main")
}

if(mongo.is.connected(mongo) == TRUE) {
  mongo.find.one(mongo, "simpledb.main")
}

#Code needed for Shiny UI
ui <- fluidPage(
  fluidRow(
    column(2, textInput(inputId = "userName", label = "", value = "Enter name here"))),
  mainPanel(plotOutput(outputId = "main_plot"))
)

#Code needed for Shiny server
server <- function(input, output) {

  queryReactive <- reactive({
     nameFinal <- paste0(input$userName)
     query = mongo.bson.buffer.create()
     mongo.bson.buffer.append(query, "user", nameFinal)
     query = mongo.bson.from.buffer(query)
  })
 #Run the query and store results as an R list object
 queryresults <- mongo.find.all(mongo=mongo, ns = coll, query=queryReactive)

 #Convert the R list object into a data frame
 resultsdf <- data.frame(matrix(unlist(queryresults), nrow=length(queryresults), byrow=T), stringsAsFactors=FALSE)

  output$main_plot <- renderPlot({boxplot(as.numeric(resultsdf$X3))})

}

#Code needed to call Shiny UI and server
shinyApp(ui = ui, server = server)

Solution

  • There is no need for a reactive command in your server function. I have simplified and corrected your function below:

    server <- function(input, output) {
    
      output$main_plot <- renderPlot({
        nameFinal <- paste0(input$userName)
        query = mongo.bson.buffer.create()
        mongo.bson.buffer.append(query, "user", nameFinal)
        query = mongo.bson.from.buffer(query)
        queryresults <- mongo.find.all(mongo=mongo, ns = "simpledb.main", query=query)
        if (length(queryresults) > 0) {
            resultsdf <- data.frame(matrix(unlist(queryresults), nrow=length(queryresults), byrow=T), stringsAsFactors=FALSE)
            boxplot(as.numeric(resultsdf$X3))
        }
        else boxplot(c(0))
     })
    
    }