Shiny modules - Previewing saved plots in reactive values not working after clicking save button

I am writing an app that should save a ggplot created into reactive value once user click save button. User can save a few plots and I want to add an option to preview selected plot in Preview tab. It works in the way that user choose a variable which changes the ggplot and then can save a plot by typing a name and preview of that plot is being shown below (for the moment I have a first plot in a list there). The problem is that now when user save any plot and then change Variable input the plot in preview is immediately changed to the one above without saving.

I am wondering what i am doing wrong and what would be possible solution to preview only plots that are saved!

It works all great without modules..

Here is my app:

server.R

library(shinyjs)
library(ggplot2)
library(shiny)
library(shinyFeedback)
source("mod_save_plot_button.R")
#source("mod_preview.R")

shinyServer(function(input, output, session) {
  # #define reactive values
  value <- reactiveValues(p = list())
  
  data <- reactive(mtcars[[input$var]])
  main_Plot <- reactive({
    p <-
      ggplot(mtcars, aes(x = data())) + geom_histogram(stat = "count", binwidth = 10)
    return(p)
  })
  
  output$hist <- renderPlot({
    main_Plot()
  }, res = 96)
  
  ########### SAVE PLOT ######
  
  save_plot_buttonServer("1", values = value,  new_plot = isolate(main_Plot()))
  
  # ----------- Export tab -----------
  
  # Create a server variable that we can use in the UI for a conditionalPanel
  output$saved_plots_exist <- reactive({
    length(value$p) > 0
    
  })
  outputOptions(output, 'saved_plots_exist', suspendWhenHidden = FALSE)
  
  output$plot_preview <- renderPlot({
    value$p[1]
    
  })
  
})

ui.R

source("mod_save_plot_button.R")
source("mod_preview.R")

shinyUI(
  fluidPage(
    useShinyjs(),
    selectInput("var", "Variable", names(mtcars)),
    plotOutput("hist"),
    
    ### export ###
    save_plot_buttonUI("1"),
    
    conditionalPanel(condition = "!output.saved_plots_exist",
                     h2("You do not have any saved plots to export")),
    conditionalPanel(condition = "output.saved_plots_exist",
                     
                     fluidRow(column(4, h2("Export"),
                     #mod export
                     # export_UI("1"))),
                     column(
                       8, h2("Preview"),
                       #mod preview
                       plotOutput("plot_preview")
                       
                     ))
                     
                     )
    )
  )
)

module:

save_plot_buttonUI <- function(id) {
  shiny::tagList(div(
    id = NS(id, "save_plot_area"),
    inline_ui(textInput(
      NS(id, "save_plot_name"), NULL, "",
      placeholder = "Enter plot name"
    )),
    actionButton(NS(id, "save_plot_btn"), "Save plot"),
    shinyjs::hidden(span(
      id = NS(id, "save_plot_checkmark"),
      icon("check")
    ))
  ))
}



inline_ui <- function(tag) {
  div(style = "display: inline-block", tag)
}


save_plot_buttonServer <- function(id,values = value,  new_plot) {
  moduleServer(id, function(input, output, session) {
    
    #define reactive values
   
  
    # When the save button is clicked, add the plot to a list and clear the input
    observeEvent(input$save_plot_btn, {
      
      values$click <- rnorm(1)
      
      plot_name <- trimws(input$save_plot_name)
      
      if (plot_name %in% names(values$plots)) {
        shinyFeedback::showFeedbackWarning(inputId = "save_plot_name",
                                           text = "Plot with that name already exists.")
       
      } else {
        #no message when no name duplication
        hideFeedback(inputId = "save_plot_name" )
        shinyFeedback::showFeedbackSuccess(inputId = "save_plot_name",
                                           text = "Plot saved",
                                           icon = shiny::icon("ok", lib = "glyphicon"))
      #save plot to reactive values
        values$p[[plot_name]] <- isolate(new_plot)
        updateTextInput(session, "save_plot_name", value = "")
        shinyjs::delay(
          10,
        hideFeedback(inputId = "save_plot_name" )
        )
      }
    })
   
    # Disable the "save" button if the plot name input is empty
    observe({
      shinyjs::toggleState("save_plot_btn",
                           condition = nzchar(trimws(input$save_plot_name)))
      
    })

    return(values)
  })
}

Here the SO crosspost can be found.

This topic was automatically closed 54 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.