Any compatibility issues between if else statement and reactive()? or would you help me with finding anything I missed?

Everything works fine when "A" is selected, but not with "B". Am I using something wrong? It does not shut down the app but does not make the tibble as intended. When I tried to print a statement saying if strategy B was selected, it was never successfully selected/printed. Does anyone have any idea what's wrong here?

When reactive() fails to read if/else if statements, is there another way to revise the codes? I have seen someone using switch with lists, but I'm unsure how that would work with tibble instead of lists.

Below are my current ui and server.

shinyUI(fluidPage(
  titlePanel("Shiny"),
  sidebarLayout(
    sidebarPanel(
      a(
        "Guide",
        href = " ",
        target = "_blank"
      ),
      fileInput("fileUpload", "Upload CSV/XLSX File", accept = c(".csv", ".xlsx")),
      selectInput(
        "Strategy",
        "Choose a Strategy",
        choices = c(
          "Select",
          "A", 
          "B"
        )
      ),
      
      
      # Conditional Panel for A
      conditionalPanel(condition = "input.Strategy == 'A'",
                       fluidRow(
                         column(
                           width = 8,
                           textInput('Objective.a', 'Objective', ""),
                           textInput('Latency.a', 'Latency', "3 sec"),
                           textInput('Step 1.a', 'Step 1', ""),
                           textInput('Step 2.a', 'Step 2', ""),
                           textInput('Step 3.a', 'Step 3', ""),
                           textInput('Step 4.a', 'Step 4', ""),
                           textInput('Step 5.a', 'Step 5', ""),
                           actionButton("Generate", "Generate Template")
                         ),
                       )),
      
      # Conditional Panel for B
      conditionalPanel(condition = "input.Strategy == 'B'",
                       fluidRow(
                         column(
                           width = 8,
                           textInput('Objective.b', 'Objective', ""),
                           textInput('Latency.b', 'Latency', ""),
                           textInput("Item 1.b", "Item 1", value = ""),
                           textInput("Item 2.b", "Item 2", value = ""),
                           textInput("Item 3.b", "Item 3", value = ""),
                           textInput("Item 4.b", "Item 4", value = ""),
                           textInput("Item 5.b", "Item 5", value = ""),
                           actionButton("Generate", "Generate Template")
                         ),
                       )),
    ),
    
    mainPanel(
      downloadButton('downloadData', 'Download Data'),
      tableOutput('show_inputs'),
      numericInput("goalPercentage", "Goal Percentage:", 60, min = 0, max = 100),
      actionButton('graph', 'Make A Graph'),
      plotOutput("result")
    )
  )
))
library(dplyr)
library(tidyr)
library(tibble)
library(shiny)
library(ggplot2)

shinyServer(function(input, output, session) {
  AllInputs <- reactiveVal(tibble())
  Filtered <- reactiveVal(tibble())

  observeEvent(input$Generate, {
    inputData <- reactive({
      if (input$Strategy == "A") {
        tibble(
          Objective = input$'Objective.a',
          Latency = input$'Latency.a',
          'Step 1' = input$'Step 1.a',
          'Step 2' = input$'Step 2.a',
          'Step 3' = input$'Step 3.a',
          'Step 4' = input$'Step 4.a',
          'Step 5' = input$'Step 5.a'
        )
      } else if (input$Strategy == "B") {
        tibble(
          Objective = input$'Objective.b',
          Latency = input$'Latency.b',
          'Item 1' = input$'Item 1.b',
          'Item 2' = input$'Item 2.b',
          'Item 3' = input$'Item 3.b',
          'Item 4' = input$'Item 4.b',
          'Item 5' = input$'Item 5.b'
        )
      }
    })

    currentInputs <- inputData()
    
    newData <- tibble(
      key = names(currentInputs),
      value = unlist(currentInputs, use.names = FALSE)
    )
    
    if (ncol(AllInputs()) == 0) {
      AllInputs(newData)
    } else {
      newData <- tibble(value = unlist(currentInputs, use.names = FALSE))
      colIndex <- ncol(AllInputs()) - 1
      colName <- paste0('date ', colIndex)
      newData <- newData |>
        rename_at(vars(value), ~ colName)
      AllInputs(bind_cols(AllInputs(), newData))
    }
  })
  
  observeEvent(input$graph, {
    correct_response_symbol <-
      ifelse(input$Strategy == "B", "CA", "+")
    properties <-
      c(
        'Objective',
        'Latency'
      )
    
    filteredData <- AllInputs()
    
    filteredData <- filteredData |>
      filter(!(key %in% properties))
    
    NumCorrect <- filteredData |>
      summarise(across(-key, ~ sum(. == '+', na.rm = TRUE))) |>
      mutate(key = "NumCorrect")  |>
      select(key, everything()) |>
      mutate(across(-key, as.character))
    
    PercentCorrect <- filteredData |>
      summarise(across(-key, ~ round(
        sum(. == '+', na.rm = TRUE) / sum(!is.na(.)) * 100, 1
      ))) |>
      mutate(key = "PercentCorrect")  |>
      select(key, everything()) |>
      mutate(across(-key, as.character))
    
    filteredData <-
      bind_rows(filteredData, NumCorrect, PercentCorrect)
    Filtered(filteredData)
  })
  
  output$show_inputs <- renderTable({
    AllInputs()
  })
  
  output$result <- renderPlot({
    plotData <- Filtered() |>
      slice(n()) |>
      select(-c(1, 2))
    
    longPlotData <- plotData |>
      pivot_longer(cols = everything(),
                   names_to = "Date",
                   values_to = "Percentage") |>
      mutate(Date = as.factor(Date)) |>
      mutate(Percentage = as.numeric(as.character(Percentage)))
    
    ggplot(longPlotData, aes(x = Date, y = Percentage)) +
      geom_bar(stat = "identity", fill = "skyblue") +
      geom_hline(
        aes(yintercept = input$goalPercentage),
        color = "red",
        linetype = "solid"
      ) +
      geom_text(
        aes(
          x = Inf,
          y = input$goalPercentage,
          label = "Goal!",
          vjust = -0.5
        ),
        hjust = 1.05,
        color = "red"
      ) +
      theme_minimal() +
      theme(
        axis.text.x = element_text(hjust = 1, size = 12),
        axis.text.y = element_text(size = 12),
        axis.title.x = element_text(size = 14),
        axis.title.y = element_text(size = 14),
        plot.title = element_text(size = 16, hjust = 0.5)
      ) +
      labs(x = "Date", y = "Independent/Correct Response", title = "Student's Progress Monitoring") +
      ylim(0, 100) +
      scale_x_discrete(
        labels = function(x)
          gsub(".*?(\\d+).*", "\\1", x)
      )
  })
  
  output$downloadData <- downloadHandler(
    filename = function() {
      paste("progress-monitoring-", Sys.Date(), ".csv", sep = "")
    },
    content = function(file) {
      allInputs <- AllInputs()
      
      write.csv(allInputs, file, row.names = FALSE)
    }
  )
})

Again, everything works as intended EXCEPT else if (input$Strategy == "B") part. I may have missed parentheses or commas while revising the codes to erase unrelated parts; please disregard if you find anything missing. Thank you so much!

Shiny requires that inputs you put in your ui have unique ids, and yours arent all unique

You mean they should be named uniquely even though it's in different control panels?

Updates: unique ids haven't solved any issues yet

the way you've set it up, its not possible for currentInputs / newData/ AllInputs to change without pressing the generate button; if you werent aware of that, it may explain why you dont get expected behaviour ?

That's what I meant. But if that was the issue, isn't it supposed to work properly (i.e., selecting strategy B) when the shiny app first started?

I dont think I will attempt to wrestle further with your issue, without your updating the code to have the unique ids as discussed.

I can suggest to you that you might help yourself by using browser() or debug() functions to step through your code , and in that way validate to yourself how things are working.
You can also sprinkle print statements to tell yourself when you check the console as the app runs what happened; you can get some of this out of the box via package logger with logger::log_shiny_input_changes()

I added unique ids, as I mentioned in the comment above, and nothing really changed. I just didn't update the codes here.

I have also added "print("A strategy selected")" to validate each step, and it is where the else if (input$Strategy == "B") part I don't get the statement printed. Thanks for your help though!

Print out what the strategy is, and youll probably see that it is A?

When A is selected on the sidebar, yes, it successfully prints "A strategy selected." I added the same line for B, but it doesn't print any statement when I select B on the sidebar, which should be indicating the B is not even selected. There should be more strategies after B, so I've tried different conditions after A... But still not selecting any other strategy than A, which was why I was pretty sure something was going wrong with the else-if statement. I appreciate your patience with me. I haven't been good at describing what's going on...

Id like to review your version with the ids made unique if you would share it ?

I've edited the scripts above. I just added '.a' or '.b' for each strategy. Still not selecting time delay... or should I rename actionButton uniquely, too?

Oh gosh, I think that really was the issue. I moved the actionButton out of the control panels, and it finally works properly. Thank you so so so much!!!

Good that your issue is solved.

I wouldnt know about the uniqueness requirement if i hadnt learnt that lesson hard myself.

It can be really frustrating, for sure... I appreciate your help!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.