r shiny observe function clears text input - r

Hi I am trying to build a login page that contacts an API service and validates user credentials. If the credentials are correct then a new user interface appears and simply makes a plot. If it is not correct a message at the login screen should say "incorrect login". Currently, when I try to type in either of the fields at the login page (ui1.r) the field refreshes/wipes itself after a second or so, thus preventing me from passing on user input to the API. I have the following files
server.r:
rm(list = ls())
library(shiny)
library(dplyr)
library(shinyjs)
umls <- dbConnect(drv=RSQLite::SQLite(),
dbname="/media/sf_umls-2018AA-full/2018AA-full/2018AA/META/umls_browser.sqlite3")
licenseCode <- "mylicense"
shinyServer(function(input, output) {
source('ui1.R') #login page
output$page <- renderUI({ ui1 })
observe({
z<-system(paste("perl", "/media/sf_umls-2018AA-full/2018AA-full/2018AA/META/umls_auth.pl",
input$user, input$password),intern=TRUE)
if (grepl("false",z[22])) {
renderText("incorrect login")
}
if (grepl("true",z[22]))
{
output$page <- renderUI({ ui2 })
output$table <- renderTable({mtcars()})
}
})
})
ui1.r
ui1 <- shinyUI(fluidPage(
# Application title
titlePanel("UMLS Constraint Browser"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
textInput("user", "User",""),
textInput("password", "Password",""),
actionButton("login", "Login")
),
mainPanel(
tableOutput("table")
)
)
))
What appears to be the problem?

I think the problem comes from the observe function. Each time you write a letter, it sends a request to your credential database. You should try to use
ObserveEvent instead :
shinyServer(function(input, output) {
observeEvent(input$login, {
z<-system(paste("perl", "/media/sf_umls-2018AA-full/2018AA-full/2018AA/META/umls_auth.pl",
input$user, input$password),intern=TRUE)
if (grepl("false",z[22])) {
renderText("incorrect login")
}
if (grepl("true",z[22]))
{
output$page <- renderUI({ ui2 })
output$table <- renderTable({mtcars()})
} })
})
Here, a request is made only when the user clicks on the login button. Tell me if it works for you.

Related

How to alert if user not log in in shiny?

I use the googleAuthR package in shiny, I want to alert users if they are not log in and I also want to save user's google id if they have successfully logged in. But sign_ins() is reactive consumer that I cannot do this. Any suggestions?
library(shiny)
library(googleAuthR)
library(shinyWidgets)
options(googleAuthR.webapp.client_id = "**********************")
ui <- fluidPage(
titlePanel("Sample Google Sign-In"),
sidebarLayout(
sidebarPanel(
googleSignInUI("demo")
),
mainPanel(
with(tags, dl(dt("Name"), dd(textOutput("g_name")),
dt("Email"), dd(textOutput("g_email")),
dt("Image"), dd(uiOutput("g_image")) ))
)
)
)
server <- function(input, output, session) {
sign_ins <- shiny::callModule(googleSignIn, "demo")
output$g_name = renderText({ sign_ins()$name })
output$g_email = renderText({ sign_ins()$email })
output$g_image = renderUI({ img(src=sign_ins()$image) })
if(is.null(sign_ins())){
shinyWidgets::show_alert(title = "not log in",
type = NULL,
btn_labels = "Ok")
else{
write.csv(sign_ins(),"file.csv")
}
}
}
# Run the application
shinyApp(ui = ui, server = server)
I'm not familiar with googleAuthR but every google-api product in R is most likely has "*_has_token" feature to validate if there is an active credential logged in the session. I've checked the googleAuthR package and i think you can use googleAuthR::gar_has_token(). So instead of
if(is.null(sign_ins())) {...}
you can use
if(googleAuthR::gar_has_token() == FALSE){...}
to check if there is an active credentials and do your things.
Hope this helpful

Change a reactiveVal twice within one observeEvent handler

My Shiny application runs a script build.R when the user clicks the action button. I would like to inform the user not to close the app while the script is being run. When done, the user is informed that building was successful.
Here's my minimal reproducible code:
library(shiny)
ui <- fluidPage(
actionButton("build", "run the buildscript"),
textOutput("rstatus")
)
server <- function(input, output, session) {
reloadstatus <- reactiveVal("")
observeEvent(input$build, {
reloadstatus("building, do not close the app")
# in the actual app would be source("build.R")
Sys.sleep(1)
reloadstatus("successfully built")
})
output$rstatus <- renderText({
reloadstatus()
})
}
shinyApp(ui, server)
I guess it does not work because Shiny tries to first run the observeEvent till the end before altering the reactiveVal. How can I achieve my desired output (first "reloading..." second "successfully...")?
You can use shinyjs to update the content of message.
library(shiny)
library(shinyjs)
ui <- fluidPage(
shinyjs::useShinyjs(),
actionButton("build", "run the buildscript"),
p(id = "rstatus", "")
)
server <- function(input, output, session) {
observeEvent(input$build, {
shinyjs::html("rstatus", "building, do not close the app")
# in the actual app would be source("build.R")
Sys.sleep(1)
shinyjs::html("rstatus", "successfully built")
})
}
shinyApp(ui, server)

Action button in Shiny app updates query in url with input from user

I have this app:
library(shiny)
ui <- fluidPage(
textInput("query_text","Type something:"),
actionButton(inputId='query_button',
label="Search",
icon = icon("th"),
onclick = paste("location.href='http://www.example.com?lookfor=",
input$query_text, "'", sep=""))
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
I'd like to update the url with the action button, so when the user types something (for example: paper), it updates the url like this:
http://www.example.com/?lookfor=paper
Any ideias how to do it? Maybe wrapping it on a observeEvent?
Based on your replies to my comment, what you're looking for is the updateQueryString function.
library(shiny)
ui <- fluidPage(
textInput("query_text", "Type something:"),
actionButton(inputId = 'query_button', label = "Search")
)
server <- function(input, output, session) {
observeEvent(input$query_button, {
updateQueryString(paste0("?lookfor=", input$query_text))
})
}
shinyApp(ui, server)

Redirect in Shiny app

I'm trying to make my Shiny app to redirect the user to another page. I'm using httr to send GET requests and see if the user is logged in. If he's not, I want to redirect him to another link.
Can I do that using R / Shiny only, or do I need some extra libraries?
sample:
library(httr)
library(shiny)
shinyServer(function(input, output) {
rv <- reactiveValues()
rv$mytoken = session$request$token
observeEvent(input$button1, {
rv$a <- GET("my.url:3405/authtoken",
add_headers(
.headers = c("token" = rv$mytoken)
))
if (rv$a$status_code == 200) {
} else {
# redirect magic
}
})
}
shinyUI(fluidPage(
actionButton(button1, "btn")
))
Here this will navigate you to google if not true
library(shiny)
jscode <- "Shiny.addCustomMessageHandler('mymessage', function(message) {window.location = 'http://www.google.com';});"
ui <- fluidPage(
tags$head(tags$script(jscode)),
checkboxInput("Redirect","Redirect",value = T)
)
server <- function(input, output, session) {
observeEvent(input$Redirect,{
if(!input$Redirect){
session$sendCustomMessage("mymessage", "mymessage")
}
})
}
shinyApp(ui,server)
Just to update. There is also an easier way...
shinyjs::runjs(paste0('window.location.href = "...";'))
Don't forget useShinyjs() in UI.

R Shiny Bookmark Button Flaw

I have found a major flaw with the bookmarkButton() in Shiny. If you have any text inputs and do not enter anything in them, when you go to bookmark your app's state and restore it, it gives you an error:
Error in RestoreContext initialization: Failed to parse URL parameter "txt"
This is because the URL that the bookmarkButton() creates always has the value of text inputs between %22s. When there's no input, the URL looks like this ...TextInputID=%22%22. If you enter something in the text input the URL will look something like ...TextInputID=%22foo%22.
See this example app to reproduce this error. Is there a way around this? Maybe a way to get in there and edit the URL that the bookmarkButton() produces?
ui <- function(request) {
fluidPage(
textInput("txt", "Enter text"),
checkboxInput("caps", "Capitalize"),
verbatimTextOutput("out"),br(),
sliderInput("slider", 'Choose a number:', 1, 100, 20),
verbatimTextOutput("sliderOut"),
bookmarkButton()
)
}
server <- function(input, output, session) {
output$out <- renderText({
if (input$caps)
toupper(input$txt)
else
input$txt
})
output$sliderOut <- renderText({
input$slider
})
}
shinyApp(ui, server, enableBookmarking = "url")

Resources