bretauv
bretauv

Reputation: 8506

R Shiny: how can I import data based on row selection?

I am aware that the title is not very clear so I'll do my best to explain my problem.

I am writing an app that aims to import data from the World Bank website. To do so, I use the WDI package and more particularly the WDIsearch and WDI functions. The former uses the word you put in to search indicators related to that word on the World Bank website. The latter imports data based on the indicator code you put in the function.

In my app, I would like first to search indicators of the World Bank. The results would be displayed in a dataframe with indicator code in first column and description of the indicator in second column. I am able to do that and to display the choices. Then, I would like that clicking on one of the row imports the data related to the indicator code of that row in a new dataframe. I know you can use _selected_rows as inputs (based on here) to do so. The problem is that I think this code needs datatable, but datatable makes it impossible to select columns.

As soon as I click on "Validate" in my app, I have an error message:

Warning: Error in :: l'argument est de longueur nulle (argument is of length zero or NULL, I don't know what the message is in English)

Here's a reproducible example:

library(pacman)
pacman::p_load(shiny, WDI, DT, data.table, dplyr, shinydashboard, shinyWidgets)

ui <- dashboardPage(
  dashboardHeader(title = ""),
  dashboardSidebar(
    sidebarMenu(
      menuItem("Test", tabName = "Test")
    )),
  dashboardBody(
    tabItems(
      tabItem(tabName = "Test",
              textInput("theme_bdd",
                        "Search",
                        placeholder = "Ex : agriculture"),
              actionButton("search", 
                           "Validate"),
              br(),
              br(),
              dataTableOutput("indicators_to_select"),
              br(),
              dataTableOutput("data_imported")
      )
    ) 
  )
)


server <- function(input, output, session) {

  indicators_to_search <- eventReactive(input$search, {
    WDIsearch(string = input$theme_bdd, field = 'name')
  })

  global <- reactiveValues(indicators_to_search = NULL)

  output$indicators_to_select <- renderDataTable({
    global$test <- data.table(indicators_to_search(), 
                                 selection = "single")
    global$test
  })

  output$data_imported <- renderDataTable({
    if(!is.null(global$test)){
      data <- global$test
      as.data.frame(WDI(country = "all", 
                        indicator = data[input$indicators_to_select_rows_selected, 1]
      )
      )
    }
  })

}

shinyApp(ui, server)

Does anybody have a solution?

Upvotes: 1

Views: 71

Answers (1)

Yifu Yan
Yifu Yan

Reputation: 6106

Use req instead of if condition. Yes, they have the same functionality, but req is easier to write and read.

Also, it seems like the downloading takes a while, you may also need to add a loading icon after the row is selected.

output$data_imported <- renderDataTable({
    req(global$test)
    req(input$indicators_to_select_rows_selected)
    data <- global$test
    as.data.frame(WDI(country = "all", 
                      indicator = data[input$indicators_to_select_rows_selected, 1]
})

Upvotes: 1

Related Questions