0

Edited to add reproducible code

I am building a Shiny app and encountered a problem with a while loop inside an observe function. The program does not display the reactive values after while loop. Here is the relevant code snippets from ui.r and server.r

ui.r

library(shiny)
shinyUI(fluidPage(
  sidebarLayout(
    sidebarPanel(
       textAreaInput("inText", label = "Enter text", rows = 3),
       submitButton("Predict")
    ),

    mainPanel(
      textOutput("outText"),
      textOutput("outCount"),
      textOutput("outPred")
    )
  )
))

Server.r

library(shiny)
library(stringr)

predict <- function(term)
{
  if(term == 3)
    table <- list()
  else
    if(term == 0)
      table <- c("input","text","empty")
    else
      table <- c("words","were","found")
  return(table)
}

shinyServer(
  function(input, output) {
    state <- reactiveValues()
    observe({
      state$inText <- input$inText
      state$wcount <- sapply(gregexpr("[[:alpha:]]+", state$inText), function(x) sum(x > 0))

      if( state$wcount > 2)
        term.c <- 3
      else
        if( state$wcount == 2)
          term.c <- 2
        else
          if( state$wcount == 1)
            term.c <- 1
          else
            term.c <- 0
      cont <- TRUE

      while(cont == TRUE) {
        if(term.c == 3) {
          state$predList <- predict(term.c)
          if(length(state$predList) > 0) break
          else term.c <- 2
        }
        if(term.c == 2) {
          state$predList <- predict(term.c)
          if(length(state$predList) > 0) break
          else term.c <- 1
        } 
        if(term.c == 1) {
          state$predList <- predict(term.c)
          if(length(state$predList) > 0) break
          else term.c <- 0
        } 
        if(term.c == 0) {
          state$predList <- c("Did", "not", "find", "term")
          break
        }
      }
    })
    output$outText <- renderPrint({ input$inText })
    output$outCount <- renderPrint({ sapply(gregexpr("[[:alpha:]]+", input$inText), function(x) sum(x > 0)) })
    output$outPred <- renderPrint({ state$predList })
  }
)

Enter two words and the values are displayed properly. Enter three words and an empty list is returned to state$predList which will give it a 0 length. the program should then execute the second if statement and populate state$predList with a non-zero length list. this happens but the display is never refreshed and the program goes into an infinite loop. It jumps to the first line of the observe function and continues in an infinite loop. I see this when I add browser().

Am I not using the reactive values correctly? Thanks for any assistance.

Step
  • 11
  • 2
  • 2
    It would be easier to help if you included a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). Right now we can't copy/paste this into R to test it to see what's really happening. Try simplifying the example. – MrFlick Jun 15 '17 at 18:39
  • 1
    Your example works fine, if I remove the `predict` expressions and replace them with something simple. Do you use break points for debugging? Did you define a `textOutput("outPred")` in the UI? – shosaco Jun 15 '17 at 19:01
  • My apologies, I have created a reproducible example of the problem I am experiencing. In the actual program, a search that doesn't find anything returns an empty list. So I've created this example so that if you enter three words it will also return an empty list. Both programs then perform another `predict` function which returns a populated list but it is never displayed. @MrFlick @shosaco – Step Jun 16 '17 at 17:47
  • Try wrapping your `while(){}` loop with `isolate({})`. Right now you are using your reactive values for both input and output so when you update the values you are creating an infinite loop. – MrFlick Jun 16 '17 at 18:43
  • Thanks so very much. I had been struggling with this for two weeks. Your suggestion did the trick. – Step Jun 16 '17 at 19:05

0 Answers0