D. Spada
D. Spada

Reputation: 21

R shiny doesn't reset fileInput and and keeps it in memory

I'm working with a R Shiny app that takes two shapefiles in input and then intersects them together and calculates the area. I want to reset and remove the second shapefile in input when the first shapefile is uploaded so at the new analysis I want to set the second shapefile (file2) as NULL. I tried using shinyjs::reset("file2") but the second shapefile (input$file2) is still in memory and when I upload a new shapefile (file1, input$file1) and then click on analysis button (whithout upload another file2) the app starts analysis such as file2 was not resetted.

This is the code that I'm using:

library and function

      library(shiny)
      library(shinyjs)
      library(leaflet)
      library(mapview)
      library(rgdal)
      library(rgeos)
      library(maptools)
      library(DT)


        fIntersect<-function(file1,file2){
        CRSfrom <- CRS("+proj=utm +zone=33 +datum=WGS84 +units=m+no_defs")
        CRSto   <- CRS("+proj=longlat +datum=WGS84")
        shpInt <- disaggregate(intersect(file1, file2))
        shpInt@data$area<- round(gArea(shpInt, byid = TRUE) / 10000,digits= 2)
        IntData<-data.table(shpInt@data)
        return(list("IntData"=IntData))           
        }

ui.R

    ui <- fluidPage( 
    useShinyjs(),
    fileInput('file1', 'Choose File',multiple = TRUE),
    fileInput('file2', 'Choose File',multiple = TRUE),
    actionButton("Analize", "Analize"),

    box(leafletOutput("Map",width ="100%")),  

    box(dataTableOutput("IntData"))),

server.R

    server <- function(input, output) {
    #CRS setting            
    CRSfrom <- CRS("+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs")
    CRSto   <- CRS("+proj=longlat +datum=WGS84")

    #Render Input file and upload           
    output$Map <- renderLeaflet({
        leaflet() %>%setView(16,40,zoom=6)%>%
            addTiles() })


    output$file1 <- renderText({
        file1 <- input$file1
        if (is.null(input$file1))
            return(NULL)
    })

    output$file2 <- renderText({
        file2 <- input$file2
        if (is.null(file2))
            return(NULL)
    })


    uploadfile1 <- reactive({
        if (!is.null(input$file1)) {
            shpDF <- input$file1
            prevWD <- getwd()
            uploadDirectory <- dirname(shpDF$datapath[1])
            setwd(uploadDirectory)
            for (i in 1:nrow(shpDF)) {
                file.rename(shpDF$datapath[i], shpDF$name[i])
            }
            shpName <- shpDF$name[grep(x = shpDF$name, pattern = "*.shp")]
            shpPath <- paste(uploadDirectory, shpName, sep = "/")
            setwd(prevWD)
            file <- readShapePoly(shpPath,
                                  proj4string =CRS("+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs"))
            return(file)


        } else {
            return(NULL)
        }
    })

    uploadfile2 <- reactive({
        if (!is.null(input$file2)) {
            shpDF <- input$file2
            prevWD <- getwd()
            uploadDirectory <- dirname(shpDF$datapath[1])
            setwd(uploadDirectory)
            for (i in 1:nrow(shpDF)) {
                file.rename(shpDF$datapath[i], shpDF$name[i])
            }
            shpName <- shpDF$name[grep(x = shpDF$name, pattern = "*.shp")]
            shpPath <- paste(uploadDirectory, shpName, sep = "/")
            setwd(prevWD)
            file <- readShapePoly(shpPath,
                                  proj4string =CRS("+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs"))
            return(file)
        } 
        else {
            return(NULL)
        }
    })

    output$IntData  <- renderDataTable(datatable(data.table("id" = "0")))

    observeEvent(input$file1, {
        # Show upload polygon on Map
        shinyjs::reset('file2')
        leafletProxy("Map")%>%clearGroup(c("file1")) ####
        shpUpload <- spTransform(uploadfile1(), CRSto)
        leafletProxy("Map") %>%
            addPolygons(data = shpUpload,
                        color = "#33a02c",
                        group = "file1",
                        fill = FALSE,
                        weight = 2.5)
    })

    observeEvent(input$file2, {
        # Show upload polygon on Map
        leafletProxy("Map")%>%clearGroup(c("file2")) ####
        shpUpload <- spTransform(uploadfile2(), CRSto)
        leafletProxy("Map") %>% 
            addPolygons(data = shpUpload,
                        color = "#33a02c",
                        group = "file2",
                        fill = FALSE,
                        weight = 2.5)
    })


    #Start analysis            
    observeEvent(input$Analize,{

        if(input$Analize>0){ withProgress(message = "Sto eseguendo l'analisi...",
                             value =0, {
                             Intersection<-fIntersect(uploadfile1(),uploadfile2())
                             observe({
                             output$IntData<-renderDataTable({
                             datatable(Intersection$IntData)
                             })
                       })

                 }
        )
        }else{}

    }

    )
    #End Analysis            
}

shinyApp(ui, server)

Thanks for any advice.

Upvotes: 1

Views: 2025

Answers (1)

Harlan Nelson
Harlan Nelson

Reputation: 1502

This code shows how to create your own reativeValues to gain the control you want. First create your own writable reactive values, then use those instead of input.

library(shiny)
library(DT)
library(shinyjs)
# Define UI for application that draws a histogram
ui <- fluidPage( 
  fileInput('file1', 'Choose File',multiple = TRUE),
  fileInput('file2', 'Choose File',multiple = TRUE),
  actionButton("Analize", "Analize"),
  # Show the state of the input files
  verbatimTextOutput('file1'),
  verbatimTextOutput('file2'),
  # This will change only when the action button is used
  verbatimTextOutput('look_at_input')
)

# Define server logic required to draw a histogram
server <- function(input, output) {

  # Create your own reactive values that you can modify because input is read only 
  rv <- reactiveValues() 

  # Do something when input$file1 changes 
  # * set rv$file1, remove rv$file2
  observeEvent(input$file1, {
    rv$file1=input$file1
    rv$file2=NULL
  })

  # Do something when input$file2 changes
  # * Set rv$file2
  observeEvent(input$file2, {
    rv$file2=input$file2
  })

  # Show the value of rv$file1 
  output$file1 <- renderPrint ({ str(rv$file1) })

  # Show the value of rv$file2 
  output$file2 <- renderPrint({ str(rv$file2) })


  #Start analysis            
  # Do something when the Analize button is selected
  look_at_input<-eventReactive(input$Analize,{
    list(rv$file1,rv$file2)
  })
  output$look_at_input <-renderPrint({ str( look_at_input()    )})

  #End Analysis            
}
# Run the application 
shinyApp(ui = ui, server = server)

Upvotes: 2

Related Questions