Search code examples
rshinyshinydashboardreactive

R ShinyDashboard. Retriving data via API into a data frame after ActionButton. Function error


I am trying to create a simple app to get basic info for a firm based on its CVR (identification number). For example, by inputting LEGO's CVR number (54562519) and pressing the button "Search", API would look for it and generate a table. Here is my sample code:

Use '54562519' cvr input to test it. The API code works outside the shiny app.

library(shiny)
library(shinydashboard)
library(httr)
library(jsonlite)
library(dplyr)


header <-  dashboardHeader()
sidebar <- dashboardSidebar(sidebarMenu(
  menuItem("New Entry",tabName = "new_entry_tab", icon = icon("stats-bars", lib = 'glyphicon'))))
body <-  dashboardBody(
  tabItems(
    tabItem(tabName = "new_entry_tab",
            fluidPage(
              fluidRow(numericInput(inputId = "cvr", "Enter CVR number:",
                                                value = "cvr",
                                                min = 1000000,
                                                max = 9999999,
                                                step = NA,
                                                width = NULL)), 
              fluidRow(actionButton("button_cvr", "Search")),
              fluidRow(box(tableOutput("firm_info")))
            ))))

ui <- dashboardPage(header, sidebar, body)

# Server ----
server <- function(input, output) {
  
  
  api_firm_call <- observeEvent(input$button_cvr, {
    cvr <- input$cvr
    firm_data <- GET(paste0("https://cvrapi.dk/api?search=",cvr,"&country=dk"))
    firm <-fromJSON(rawToChar(firm_data$content))
    firm_matrix <- matrix(ncol = 1, nrow = 5)
    rownames(firm_matrix) <- c("Name", "Address", "City", "Industry", "Industry Name")
    colnames(firm_matrix) <- " "
    firm_matrix[1:5, 1] <- c(firm$name, firm$address, paste(firm$zipcode, firm$city),firm$industrycode, firm$industrydesc)
    firm_table <- tibble(firm_matrix) 
  })

  output$firm_info <- renderTable({api_firm_call()})
  
}
shinyApp(ui, server)

I receive a Warning: Error in api_firm_call: could not find function "api_firm_call", but I am don't know how to handle it.


Solution

  • Instead of using observeEvent switch to eventReactive to fix your issue as it allows to return your firm_table. Additionally I moved your code for the API search in a separate function. Doing so makes your code easier to debug, i.e. you can test the function outside of shiny, and makes your code cleaner.

    Note: To make the reprex more minimal I dropped the numericInput and hard-coded the cvr example value:

    library(shiny)
    library(shinydashboard)
    library(httr)
    library(jsonlite)
    library(dplyr)
    
    fct_api_firm_call <- function(cvr) {
      firm_data <- GET(paste0("https://cvrapi.dk/api?search=",cvr,"&country=dk"))
      firm <-fromJSON(rawToChar(firm_data$content))
      firm_matrix <- matrix(ncol = 1, nrow = 5)
      rownames(firm_matrix) <- c("Name", "Address", "City", "Industry", "Industry Name")
      colnames(firm_matrix) <- " "
      firm_matrix[1:5, 1] <- c(firm$name, firm$address, paste(firm$zipcode, firm$city),firm$industrycode, firm$industrydesc)
      tibble(firm_matrix) 
    }
    
    cvr <- "54562519"
    
    header <-  dashboardHeader()
    sidebar <- dashboardSidebar(sidebarMenu(
      menuItem("New Entry",tabName = "new_entry_tab", icon = icon("stats-bars", lib = 'glyphicon'))))
    body <-  dashboardBody(
      tabItems(
        tabItem(tabName = "new_entry_tab",
                fluidPage(
                  fluidRow(actionButton("button_cvr", "Search")),
                  fluidRow(box(tableOutput("firm_info")))
                ))))
    
    ui <- dashboardPage(header, sidebar, body)
    
    # Server ----
    server <- function(input, output) {
      
      api_firm_call <- eventReactive(input$button_cvr, {
        fct_api_firm_call(cvr)
      })
      
      output$firm_info <- renderTable({
        api_firm_call()
      })
    }
    shinyApp(ui, server)
    

    enter image description here