Can we set priority on renderPlot, i.e. let it wait after row selection value of a DT table finish?

I used a lot of DT table and plot interaction in my shiny app.

My current app have a DT table 1, a ggplot plot 2.

  • When no row in table 1 is selected, plot 2 draw an overview plot.
  • When some rows in table 1 are selected, plot 2 update to a subset of data.

Then I met this problem:

  • With table 1 and plot 2 showing some data, I moved to some other page in app to update the data behind table 1 and plot 2, then moved back to this page.
  • Table 1 and plot 2 will update to new data, but there is a brief period when some error generated.

The error is caused when

  • Table 1 underlying data has updated, but the actual rendered DT table has not changed, especially the selected rows vector has not changed, which will be cleared after table 1 update finish (it will not even be cleared previously, the newer DT fixed it by my suggestion).
  • Plot 2 is updating in same time, using the previous selected rows vector on the new underlying data, which is wrong.

If we can set some priority on the table and plots when data is updating, this can be solved. However I only found some priority on observe(), not plot rendering.

Maybe we can put the plot rendering code inside observeEvent and assign some priority?

I tried to put table 1 rendering code within an observer of data source with priority 9, and put plot within an observer with priority 1, the warning still happens.

I tried to just suppress the error, but tryCatch didn't really suppress the error. Maybe this error is thrown by shiny and cannot be suppressed? I don't want to change some global setting to suppress error altogether.

I managed to silent the warnings with suppressWarnings, and silent the error message with

tryCatch({...}, error = function(e) { req(FALSE) }). This raise silent error and stopped the plot rendering properly until the data update is finished and the plot will render again with correct data.

You can set the priority of an output using outputOptions()

Thanks, this is what I looked for as I vaguely remember there is something about priority. However this turned out still cannot prevent the error.

My guess is this can only make sure plot was executed after table, but it didn't guarantee plot update after table rendering and row selection reset finish. I still need to use the error hiding method to solve this problem.

If I understand you correctly, you need req () to tell Shiny to wait for your inputs to be ready

req will not work here, since the input is "ready"(available) but not correct - once the table finish rendering, and the row selection update finished, the plot will have correct data.

How about

if(input$something == "wrong"){
return(NULL)
})

You can set up any render function to act like an observeEvent by starting it off like this:

output$xxx = renderWhatever({trigger; isolate({
    code to render...
})})

Your trigger in this case is typically a variable you've set up with reactiveValues().

When your DT has settled down, you increment your trigger variable. The render function won't run until you do so..

I probably should make my first post more clear as my title is a little bit misleading.

  • the table and plot both got updated data and started to update
  • plot used existing table row selection value on new data, since the row selection value only get cleared after the table rendering finish.

I didn't find a way to ensure plot update after row selection value update, this happened after table render finish, and outputPriority cannot ensure this part.

I also didn't think there is a proper variable can reflect the status of row selection value update.

Previously I have used freezeReactiveValue to solve this kind of problem, but my first attempts didn't succeed. Today I realized I should freeze the row selection value before the DT datatable call. This will ensure the access from plot be hold off until all other reactive value update finish, thus solve the problem.

1 Like