polishedpayments icon indicating copy to clipboard operation
polishedpayments copied to clipboard

Call UI as function for bookmarking

Open kent-orr opened this issue 4 years ago • 4 comments

I am attempting to call my UI as a function for bookmarking my shiny application. However, even when I build a minimal example I run into cannot coerce type 'closure' to vector of type 'character' when I attempt to close the whole enchilada in:

ui <- function(request) {
    .... 
  }

Any insights would be greatly appreciated.

kent-orr avatar Oct 19 '20 16:10 kent-orr

Hi @kent-orr ,

I just updated polished so that you can supply the ui as a function. If you install the latest dev version of polished it should work.

remotes::install_github("tychobra/polished")

A couple notes:

  • under the hood, polished uses a ui function, so enableBookmarking(store = "server") should have worked even if you did not supply your ui as a function. With the most recent update to the dev version of polished, server bookmarking should now work if you supply your ui as a function or html.

  • url bookmarking does not work with polished (i.e. you have to use store = "server"). polished uses the query parameters for routing, which conflicts with bookmarked state stored in query parameters.

  • I have not tested Shiny bookmarking with polished, so please let me know if you run into issues.

merlinoa avatar Oct 20 '20 12:10 merlinoa

Thanks oodles for the quick response. Really appreciate the work y'all have contributed.

under the hood, polished uses a ui function

I had a hunch. enableBookmarking(store = "server") was working to store the inputs. Here's where I really ran into issues:

I have a renderUI that relies on a reactive value to determine the number of inputs available. I needed to store that reactive value with the bookmark to ensure that onRestore rendered the UI the same.

# ----- ui ---------

uiOutput('radios'),

actionButton('minus', "Minus"),
actionButton('plus', "Plus")

bookmarkButton(store = 'server')

# ----- server -----

output$radios <- renderUI({
  render_inputs <- function(num_) {
    radioButtons(session$ns(paste0("a-", num_)),
                 paste("label", num_),
                 c("yes", "no"))
  }

  lapply(1:plus_minus$sum, render_inputs)
})

# ----- reactive value

plus_minus <- reactiveValues(sum = 1)

observeEvent(input$plus, {
  plus_minus$sum <- plus_minus$sum + 1
})

observeEvent(input$minus, {
  plus_minus$sum <- plus_minus$sum - 1
})

# ----- bookmark items

onBookmark(function(state) {
  state$values$currentSum <- plus_minus$sum
})

onRestore(function(state) {
  plus_minus$sum <- state$values$currentSum
})

setBookmarkExclude(c("plus", "minus", "sign_out", "hashed_cookie", "go_to_payments"))

The inputs are there. If I increase plus_minus manually after loading a bookmark, it automatically fills with the saved inputs. But I cannot get the reactive value plus_minus to update via onRestore.

kent-orr avatar Oct 20 '20 14:10 kent-orr

What happens if you use onRestored() rather than onRestore(). I am thinking maybe the plus_minus <- reactiveValues(sum = 1) is executing after onRestore and overwriting the restored value of plus_minus$sum.

merlinoa avatar Oct 20 '20 17:10 merlinoa

No dice with onRestored() though I think your logic is on the money. I have plus_minus$sum printed at the top of the app and it doesn't flicker after loading a save even though I can clearly see that plus_minus$sum is bookmarked properly.

I'm going to take some time to comb over and tidy up my work to see if I can isolate the issue further. I'll chime in again when I've revisited the problem more.

kent-orr avatar Oct 20 '20 19:10 kent-orr