Troubleshooting Your App

November 20, 2024

Debugging Your App

The hard part about Shiny

Note that the server part doesn’t run line-by-line. It’s a reactive environment that will run the code when input changes.


Code only reacts when it needs to, which is why it’s called reactive programming.


This makes it hard to test your code. And it’s hard to understand what’s going on when you’re new to Shiny!

The hard part about Shiny

My personal top ways ways to get more insight into what’s going on:

  1. Use print() statements to see when something is happening
  2. Use browser() to stop the code and inspect the environment (just as you can do within functions, because that is literally what server is!)

browser() example

server <- function(input, output) {
  
    # Reactive function to fetch data
    fred_indicator <- reactive({
      browser()  # Initiate debugging here
      fredr(series_id = input$indicator,
            observation_start = start_date,
            observation_end = end_date)
    })
  
    # Reactive function to filter data
    fred_data <- reactive({
      browser()  # Debugging point to inspect filtered data
      fred_indicator() |> 
        filter(between(date, input$range[1], input$range[2]))
    })

    # Plotting function
    output$lineChart <- renderPlot({
      browser()  # Inspect before plotting
      ggplot(fred_data(), aes(x = date, y = value)) + 
        geom_line(color = "navyblue") +
        labs(x = "", y = names(vars[which(vars == input$indicator)])) +
        theme_minimal()
    })
}

Your Turn!

  • Take the toy app from this section or another one you have made
  • Try adding print() or browser() statements to see when things are happening
10:00

More App-Building Tips

Wrangle some “working data”

  • Start by selecting a manageable subset of data.
  • Focus on a few indicators for initial testing.
  • Expand data scope after validating app functionality.

Use separate files

  • Separate data wrangling and visualization into different R scripts or Quarto documents.
  • Employ glimpse() and View() to verify data structures.
  • Helps isolate and troubleshoot errors effectively.

Start building with comments and function calls

  • Use comments to outline what each code section should do.
  • Introduce function calls without arguments to build the structure.
  • This method helps in maintaining clarity and debugging.

Test your UI code separately from your server code

  • Test UI components like drop-downs and sliders without server-side logic.
  • Helps ensure that the UI layout functions as intended.
  • Use dummy server functions to isolate UI issues.

Ensure reactive data frames are called correctly

  • Use parentheses to call reactive data frames within server functions.
  • Essential for maintaining reactivity and accurate data handling.
  • Avoids common bugs related to reactive contexts.

Properly call input in server functions

  • Check that input variables are used correctly in server functions.
  • Accurate naming ensures the server reacts properly to UI changes.
  • Critical for dynamic app behavior and user interactions.

Consider nonstandard evaluation in ggplot

  • Use .data[[]] to handle user inputs within ggplot2 aesthetics.
  • Ensures dynamic plotting based on user-selected data.
  • Nonstandard evaluation simplifies coding but requires careful handling.

Understand what your code is doing

  • Maintain a clear concept of each part’s function within your code.
  • Regularly test and refine to ensure it meets your objectives.
  • Theoretical understanding aids in effective troubleshooting and innovation.

Acknowledgements