MarkEdmondson1234 / googleAuthR

Google API Client Library for R. Easy authentication and help to build Google API R libraries with OAuth2. Shiny compatible.
https://code.markedmondson.me/googleAuthR
Other
175 stars 51 forks source link

Can't use gar_shiny_ui() with {golem} #206

Closed aldomann closed 3 years ago

aldomann commented 3 years ago

What goes wrong

I've been following the example on Create a Google login before your Shiny UI launches, and while it works great when using ui and server objects, I'm not able to wrap the app_ui function (generated with {golem}) in googleAuthR::gar_shiny_ui() when calling shinyApp().

Steps to reproduce the problem

Below a simplified reproducible example of app_ui and app_server functions as created by golem::create_golem():

library(shiny)

app_ui <- function(request) {
  googleAuthR::gar_set_client(web_json = Sys.getenv("GAR_CLIENT_WEB_JSON"), activate = "web")

  tagList(
    # Leave this function for adding external resources
    # golem_add_external_resources(),
    # List the first level UI elements here
    fluidPage(
      h1("authtest")
    )
  )
}

app_server <- function(input, output, session) {
  # this is not reactive, no need as you only reach here authenticated
  googleAuthR::gar_shiny_auth(session)

  # List the first level callModules here
}

shinyApp(
  ui = googleAuthR::gar_shiny_ui(app_ui),
  server = app_server
)

Expected output

App running.

Actual output

shinyApp(
  ui = googleAuthR::gar_shiny_ui(app_ui),
  server = app_server
)
#> Error: ui is not a list

Session Info

sessionInfo()
#> R version 4.0.4 (2021-02-15)
#> Platform: x86_64-apple-darwin20.3.0 (64-bit)
#> Running under: macOS Big Sur 11.2.2
#> 
#> Matrix products: default
#> BLAS:   /usr/local/Cellar/openblas/0.3.13/lib/libopenblasp-r0.3.13.dylib
#> LAPACK: /usr/local/Cellar/r/4.0.4/lib/R/lib/libRlapack.dylib
#> 
#> locale:
#> [1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] googleAuthR_1.3.1 shiny_1.6.0      
#> 
#> loaded via a namespace (and not attached):
#>  [1] Rcpp_1.0.6        pillar_1.5.0      compiler_4.0.4    later_1.1.0.1    
#>  [5] highr_0.8         tools_4.0.4       digest_0.6.27     jsonlite_1.7.2   
#>  [9] gargle_0.5.0      evaluate_0.14     memoise_2.0.0     lifecycle_1.0.0  
#> [13] tibble_3.0.6      pkgconfig_2.0.3   rlang_0.4.10      reprex_1.0.0     
#> [17] cli_2.3.1         yaml_2.2.1        xfun_0.21         fastmap_1.1.0    
#> [21] httr_1.4.2        styler_1.3.2      stringr_1.4.0     knitr_1.31       
#> [25] fs_1.5.0          vctrs_0.3.6       glue_1.4.2        R6_2.5.0         
#> [29] fansi_0.4.2       rmarkdown_2.7     purrr_0.3.4       magrittr_2.0.1   
#> [33] backports_1.2.1   promises_1.2.0.1  ellipsis_0.3.1    htmltools_0.5.1.1
#> [37] assertthat_0.2.1  mime_0.10         xtable_1.8-4      httpuv_1.5.5     
#> [41] utf8_1.1.4        stringi_1.5.3     cachem_1.0.4      crayon_1.4.1
MarkEdmondson1234 commented 3 years ago

gar_shiny_ui is doing similar to golem here in that it takes a UI object and makes it a function so this would work:

library(shiny)
 googleAuthR::gar_set_client(web_json = Sys.getenv("GAR_CLIENT_WEB_JSON"), activate = "web")

ui_obj <- tagList(
    # Leave this function for adding external resources
    # golem_add_external_resources(),
    # List the first level UI elements here
    fluidPage(
      h1("authtest")
    )
  )

app_server <- function(input, output, session) {
  # this is not reactive, no need as you only reach here authenticated
  googleAuthR::gar_shiny_auth(session)

  # List the first level callModules here
}

shinyApp(
  ui = googleAuthR::gar_shiny_ui(ui_obj),
  server = app_server
)

I will have to think more about how to integrate them both and may need Colin's help at golem :) Untested but perhaps this?


app_ui <- function(request) {
  googleAuthR::gar_set_client(web_json = Sys.getenv("GAR_CLIENT_WEB_JSON"), activate = "web")

  ui_obj <- tagList(
    # Leave this function for adding external resources
    # golem_add_external_resources(),
    # List the first level UI elements here
    fluidPage(
      h1("authtest")
    )
  )
  # output a function that takes request
  f <- googleAuthR::gar_shiny_ui(ui_obj),
  f(request)
}
aldomann commented 3 years ago

That works beautifully, tested both in the minimal example, and in a complete {golem} package.