简体   繁体   中英

How to insert data from shiny R to MongoDB within a reactive paradigm

I have written the code all the way below. The idea is to fill in inputs in a modal generated by an actionbutton ("Open Modal"). The modal has multiple input boxes, from which I want the inputs to be converted into a character vector and be sent to MongoDB after clicking a different actionbutton ("Save Data"). So the app seems to do exactly what I want, it converts the inputvalues into a vector and sends it to MongoDB. The problem is that, the moment I click the "Save Data" actionbutton, the shiny app closes and gives the following message:

Listening on http://127.0.0.1:6960
Warning: Error in : No write concern mode named 'majority/admin' found in replica set configuration
  1: runApp

After googling I found the reason for the warning to be with the URI having an extra "&w=majority" added to it which should be deleted, but this doesn't work for me as it then gives the error that shiny R failed to parse the URI. I get the same warning if I try to insert data in MongoDB through the console and it also adds the data entry to my MongoDB database.

On stack overflow I found this post: R shiny interface for adding data into MongoDB . This person seemed to have the same problem as I have and I got the same problem (app closing with the above error) when running his code, while it did send data to MongoDB! I've tried looking on Google, but I didn't get really far. I'm guessing shiny goes into an infinite loop somewhere while connecting to MongoDB and therefore closes the app. Has anybody stumbled on this same problem and fixed it?

library(shiny)
library(mongolite)

# Modal module UI
modalModuleUI <- function(id) {
  ns <- NS(id)
  tagList(
    textOutput(ns("myText")),
    actionButton(ns("openModalBtn"), "Open Modal")
  )
}

myModal <- function(session) {
  ns <- session$ns
  modalDialog(
    title = "New Input",
    textInput("c1","Token 1"),
    textInput("c2","Amount Token 1"),
    textInput("c3","Token 2"),
    textInput("c4","Amount Token 2"),
    textInput("c5","Blockchain deployed"),
    textInput("c6","Platform deployed"),
    textInput("c7","Invested Pool"),
    actionButton("save", "Save Data"),
    footer = tagList(
      modalButton("Close"),
      actionButton(ns("save"), "Save")
    )
  )
}

# Modal module server
modalModule <- function(input, output, session) {
  
  
  # Show modal dialog on start up
  observeEvent(input$openModalBtn,
               ignoreNULL = TRUE,
               showModal(myModal(session))
  )
  
}

saveData <- function(data) {
  mongo_db_user <- "XXX"
  mongo_db_password <- "XXX"
  mongo_database <- "XXX"
  mongo_collection <- "XXX"
  mongo_clustername <- "XXX&w=majority"
  
  url_path = sprintf("mongodb://%s:%s@%s/admin",mongo_db_user,mongo_db_password,mongo_clustername)
  
  mongo_db <- mongo(collection=mongo_collection,db=mongo_database,url=url_path,verbose=TRUE)
  data <- as.data.frame(unlist(data,use.names=FALSE))
  mongo_db$insert(toJSON(data))
}


ui = dashboardPage(
  title = "Basic dashboard",
  header = dashboardHeader(),
  sidebar = dashboardSidebar(
    modalModuleUI("foo")
  ),
  controlbar = dashboardControlbar(),
  footer = dashboardFooter(),
  body = dashboardBody(
    #plotlyOutput("SNBRST")
  )
)


server = function(input, output) {
  callModule(modalModule, "foo")
  
  #Example
  a <- NULL
  b <- NULL
  c <- NULL
  d <- NULL
  e <- NULL
  f <- NULL
  g <- NULL
  
  
  values <- reactiveValues(df = data.frame(token1=a, token1_amount=b, token2=c, token2_amount=d,
                                           blockchain=e,platform=f,pool=g))
  
  input_vector <<- NULL
  
  observeEvent(input$save,{
    a_new <- c(values$df$token1,input$c1)
    b_new <- c(values$df$token1_amount,input$c2)
    c_new <- c(values$df$token2,input$c3)
    d_new <- c(values$df$token2_amount,input$c4)
    e_new <- c(values$df$blockchain,input$c5)
    f_new <- c(values$df$platform,input$c6)
    g_new <- c(values$df$platform,input$c7)
    values$df <- data.frame(token1=a_new,token1_amount=b_new,token2=c_new,token2_amount=d_new,
                            blockchain=e_new,platform=f_new,pool=g_new)
    saveData(values$df)

  })
  
}

shinyApp(ui=ui,server=server)

I've found the answer to my problem. The $insert function has as default to stop whenever an error occurs (see: https://github.com/jeroen/mongolite/issues/233 ). The corrected version is shown in the code below:

saveData <- function(data) {
  mongo_db_user <- "XXX"
  mongo_db_password <- "XXX"
  mongo_database <- "XXX"
  mongo_collection <- "XXX"
  mongo_clustername <- "XXX&w=majority"
  
  url_path = sprintf("mongodb://%s:%s@%s/admin",mongo_db_user,mongo_db_password,mongo_clustername)
  
  mongo_db <- mongo(collection=mongo_collection,db=mongo_database,url=url_path,verbose=TRUE)
  data <- as.data.frame(unlist(data,use.names=FALSE))
  mongo_db$insert(toJSON(data), stop_on_error=FALSE)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM