Shiny Modules: Simplifying Password Setup with Modular Code
In this article, we will explore how to create a simple password setup using Shiny modules. We’ll break down the concept of Shiny modules and their benefits in making our codebase more modular, readable, and maintainable.
Introduction to Shiny Modules
Shiny is an R web application framework that makes it easy to build reactive applications with a minimal amount of code. One of its key features is the ability to create modular code using shiny::module functions.
A Shiny module is a self-contained piece of code that encapsulates a specific functionality, such as a UI component or a server-side logic. By breaking down our application into smaller modules, we can make it easier to reuse and maintain individual components.
Creating the Password Module
Let’s create a password module using the passwordModuleUI and passwordModuleEval functions provided in the original code snippet:
##This part of the module is going to set modal's UI
passwordModuleUI=function(id,failed=FALSE){
ns=NS(id)
tagList(
modalDialog(
textInput(ns("username"), "Usuário:"),
passwordInput(ns("password"), "Senha:"),
footer = tagList(
# modalButton("Cancel"),
actionButton(ns("ok"), "OK")
)
)
)
}
#This will load modal UI from observer inside the server
passwordModuleShow=function(ID){
showModal(passwordModuleUI(ID))
}
#This is server side module
passwordModuleEval=function(input,output,session,id,users,passwords){
authenticated <- FALSE
isolate({
Username <- input$username
Password <- input$password
})
Id.username <- which(users == Username)
Id.password <- grep(Password,passwords)
if ((length(Id.username) > 0&nchar(Password)>1) & (length(Id.password) > 0)&nchar(Username)>1) {
if (Id.username %in% Id.password) {
authenticated <- TRUE
removeModal()
} else {
authenticated <- FALSE
}
}
return(authenticated)
}
The passwordModuleUI function generates the UI for the password input, including a modal dialog with text input and password input fields. The passwordModuleShow function loads the modal UI from an observer inside the server.
Creating the Setup Pass Protection Function
Now that we have our password module set up, let’s create the setupPassProtection function that will simplify the implementation of pass protection in Shiny apps:
#This is trying to simplify implementation in shiny apps
setupPassProtection=function(input,output,session,ID,Users,Passwords){
obs1=observe(priority = 1,{
passwordModuleShow(ID=ID)
})
observeEvent(input[[paste0(ID,"ok",sep="-")]],{
if(callModule(passwordModuleEval,ID,users=Users,passwords=Passwords))
{obs1$suspend()}
})
}
The setupPassProtection function takes in several inputs:
input: The input object from Shiny.output: The output object from Shiny.session: The session object from Shiny, which provides access to the server-side logic.ID: The ID of the password module.Users: A list of usernames to check against the password input.Passwords: A list of passwords to check against the username input.
The function uses an observer to load the modal UI for the password input and then checks if the entered username is in the list of valid users. If it is, the function returns TRUE; otherwise, it returns FALSE.
Creating the Shiny App
Finally, let’s create a simple Shiny app that demonstrates the use of our setupPassProtection function:
shinyApp(ui=basicPage(h3("testando passprotect module")),
server=function(input,output,session){
passID="test"
obs1=observe(priority = 1,{
passwordModuleShow(ID=passID)
})
observeEvent(input[[paste0(passID,"-ok")]],{
if(callModule(passwordModuleEval,"test",users=my_username,passwords=my_password))
{obs1$suspend()}
})
})
In this app, we create a basic Shiny page with a button that calls the setupPassProtection function when clicked. The function checks if the entered username is in the list of valid users and then displays or hides the modal UI accordingly.
Conclusion
In this article, we explored how to create a simple password setup using Shiny modules. We broke down the concept of Shiny modules and their benefits in making our codebase more modular, readable, and maintainable.
By creating separate modules for our password input and server-side logic, we can reuse individual components across multiple Shiny apps. This makes it easier to manage complex applications and reduces the risk of bugs and errors.
We also demonstrated how to create a setupPassProtection function that simplifies the implementation of pass protection in Shiny apps. This function takes in several inputs and checks if the entered username is in the list of valid users before displaying or hiding the modal UI.
Overall, using Shiny modules and creating custom functions like setupPassProtection can help you build more efficient, scalable, and maintainable applications.
Last modified on 2023-08-31