simplyPTA
simplyPTA

Reputation: 440

Capture stdout and returned value of a function in a reactive context

In my shiny app, I have a function which print some messages and return a value from user input. I want to capture its messages and also its value. A simple app is like this:

library(shiny)

f <- function(val) { # my function
    cat(val + 1)
    return(val)
}

ui <- fluidPage(
    sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30),
    verbatimTextOutput("console"),
    verbatimTextOutput("result")
)

server <- function(input, output) {

    txt <- reactive({ # capture its messages
        capture.output({
            res <<- f(input$bins) # capture its value
        })
    })

    output$console <- renderPrint(txt())
    output$result <- renderPrint(res)

}

shinyApp(ui = ui, server = server)

The problem is output$result is not reactive, i.e. it does not change with user input. I don't know what is proper way to do this, so for the mean time I just ask user to reload the app.

Many thanks.

Upvotes: 0

Views: 150

Answers (1)

Konrad Rudolph
Konrad Rudolph

Reputation: 545568

If you can’t control what f is doing, you can wrap it and return both values:

wrapped_f <- function (val) {
    self <- environment()
    stdout <- capture.output(self$res <- f(val))
    list(res = self$res, stdout = stdout)
}

… you can even do the same directly in the reactive expression without creating a separate function, but having a function makes the code somewhat cleaner.

Upvotes: 1

Related Questions