0

I am building an authentication part in my app by comparing the code sent in email and the code users submit. I have tried adding if-statement by using either in reactive(),isolate(), renderTable(). I either get the value should be in the reactive part error, or the app does not respond at all. Below is what I have in Server.R, the app does not respond at all with no error.

            shinyServer(function(input, output, session) {      
              myData <- reactive({
                req(input$Id)
                #connect to the database, get the data, res
                #send an email with random number, rnd
                list(res,rnd)
              })

              output$tbTable <- renderTable({req(input$Auth)
                  if (input$AuthCode==myData()$rnd) {
                myData()$res
              }
              else{
                as.data.frame(c("Authentication Failed"))
              }
              })
              output$downloadData <- downloadHandler(
                filename = function() {
                  paste(input$Id, " filname.xlsx", sep = "")
                },
                content = function(file) {
                  write.csv(myData(), file, row.names = FALSE)
                }
              )#this part need to depend on the if-statement as well
            }
            )

UI.R

                ui <- shinyUI(fluidPage(title = "aaa",
                titlePanel("aaa"),
                sidebarLayout(
                  sidebarPanel(

                    textInput("Id", "Enter Acct Name below"),
                    submitButton(text="Submit"),
                    tags$hr(),
                    numericInput("AuthCode",label="Authentication",value=""),
                    actionButton("Auth",label="Submit"),
                    tags$hr(),
                    tags$hr(),
                    downloadButton("downloadData", "Download Data")
                  ),
                  mainPanel(
                    tabsetPanel(
                      tabPanel("Data", tableOutput("tbTable"))
                    )) 
                ),
            )
            )
May Y
  • 179
  • 1
  • 20
  • why have you used this expression `as.data.frame(c("Authentication Failed"))` ? – amrrs Sep 07 '18 at 14:28
  • I am not quite clear about the data structure in Shiny. As res, the output is a dataframe, so I converted this string to dataframe to avoid mismatch. Appreciate if any input on the adverse affect if it is the problem. – May Y Sep 07 '18 at 14:40
  • Are you okay if there is a modal box saying authentication failed? – amrrs Sep 07 '18 at 14:43
  • Yes, definitely. – May Y Sep 07 '18 at 14:45
  • And why do you have the first submit button, can't it be one button for both account and authentication code? – amrrs Sep 07 '18 at 14:54
  • The email is supposed to be sent to a changeable email address based on input$Id, like the account owner, for authentication. So after the submit triggers the email, the correct recipient will enter the code in the email for authentication. So I guess there has to be 2 buttons. – May Y Sep 07 '18 at 14:58
  • Cool. You had used `submit` there which is another issue. got it! – amrrs Sep 07 '18 at 14:59
  • I read post about actionButton is preferred, but submitButton works well in older version without adding the authentication part. Really appreciate if you can help me understand this. – May Y Sep 07 '18 at 15:04

1 Answers1

0

I think I've got the fixed to do what you want. Please check. I've done the following changes

  • Replaced your submitButton to actionButton as Acc and using observeEvent to call that.

  • The authentication is also now triggered by an observeEvent when the second button is clicked

  • Excel extension wouldn't work in write.csv so changed the extension.

server.R

shinyServer(function(input, output, session) {      


# the first button will trigger this  


  observeEvent(input$Acc,{
  #  myData <- reactive({
      req(input$Id)
      #connect to the database, get the data, res
      #send an email with random number, rnd
      #list(res,rnd)
     myData <<- list(res = 123,rnd = 345) #passing test value and storing it as global variable for accessing in other functions
   # })

    cat("mydata done")

  })


  # the second button will trigger this
  observeEvent(input$Auth,{

    output$tbTable <- renderTable({
      #req(input$Auth)
      if (input$AuthCode==myData$rnd) {
        myData$res
      }
      else{
        #as.data.frame(c("Authentication Failed"))
        shiny::showModal(modalDialog(
          title = "Important message",
          "Authentication Failed!"
        ))
      }
    })
  })


  output$downloadData <- downloadHandler(
    filename = function() {
      paste(input$Id, " filname.csv", sep = "") #renamed it to csv because write.csv writes to csv not excel
    },
    content = function(file) {
      write.csv(myData, file, row.names = FALSE)
    }
  )#this part need to depend on the if-statement as well
}
)

ui.R

ui <- shinyUI(fluidPage(title = "aaa",
                        titlePanel("aaa"),
                        sidebarLayout(
                          sidebarPanel(

                            textInput("Id", "Enter Acct Name below"),
                            actionButton("Acc",label="Click to send code"),
                            tags$hr(),
                            numericInput("AuthCode",label="Authentication",value=000),
                            actionButton("Auth",label="Submit"),
                            tags$hr(),
                            tags$hr(),
                            downloadButton("downloadData", "Download Data")
                          ),
                          mainPanel(
                            tabsetPanel(
                              tabPanel("Data", tableOutput("tbTable"))
                            )) 
                        )
)
)
amrrs
  • 6,215
  • 2
  • 18
  • 27