title: Using the lapply() function in a Shiny module to build a tabBox with multiple tabPanel whose amount depends on the imported data
body: <p>I want to build a module in shiny that renders a <code>tabBox</code> with the number of <code>tabPanel</code> as a function of the data. The simulated data (see script below) has the tank or pond variable (column) (<em>&quot;viveiro&quot;</em> in Portuguese) whose quantity can be a variable. So the number of panels is a function of this variable. But the biggest problem is when inside each <code>tabPanel</code> I render a simple table (with <code>renderTable()</code>) that corresponds to a subset of each <em>&quot;viveiro&quot;</em> (tank/pond). I use the <code>lapply()</code> function both to build the <code>renderUI</code> and to assign the reactive expression to the outputs (see the applicable example below). <code>nCiclo()</code> is a reactive that represent the number of <em>&quot;viveiro&quot;</em> (tank/pond as you prefer) that can correspond to a sequence of <code>1:6</code> for example. It works well on the first <code>lapply()</code> in <code>renderUI()</code> for <code>output$tab_box</code>, but it doesn't work when I use it on the second <code>lapply()</code> for the <code>output[[paste0('outCiclo',j)]]</code> outputs in <code>renderTable</code> below.</p>
  <p><strong>Question:</strong>
  How do I put this last <code>lapply()</code> function as a function of the number of <em>&quot;viveiro&quot;</em> (tank/pond) in the simulation data? I tried to replace the fix sequence <code>1:6</code> for reactive <code>nCiclo()</code> but does not work.</p>
  <pre><code>library(shiny)
  library(shinydashboard)
  library(openxlsx) 
  rm(list = ls())
  #--------------------------------------------------
  # Simulated data for the app
  (n = 2*sample(3:8,1)) # tank/pond (portuguese viveiro) number (quantity) / random variable in the data
  bio &lt;- data.frame(
    semana = rep(1:5,n),
    peso = rnorm(5*n,85,15),
    viveiro = rep(1:2,each=(5*n)/2),
    ciclo = rep(1:n,each=5)
  )
  # An excel file will be saved to your Working Directory
  # Use the file to import into the app
  write.xlsx(bio,'bio.xlsx')
  
  #--------------------------------------------------
  
  ####### Module #######
  
  # UI Module
  dashMenuUI &lt;- function(id){
    ns &lt;- NS(id)
    
    uiOutput(ns(&quot;tab_box&quot;))
    
    
    
  }
  
  # Server Module
  dashMenuServer &lt;- function(id,df){
    moduleServer(id,function(input,output,session){
      
      ns &lt;- session$ns
      nCiclo &lt;- reactive(unique(df()$ciclo)) # nCycle is simply 1:6 sequence.
      
      output$tab_box &lt;- renderUI({
        do.call(tabBox, c(id='tabCiclo',
                          lapply(nCiclo(), function(i) {
                            tabPanel(
                              paste('ciclo', i),
                              tableOutput(outputId =  ns(paste0('outCiclo',i)) )
                            )
                          }))
        )
      })
      
      # The problem is here. I want to put the lapply function as a function of the pond/tank (portuguese viveiro) number (simulated data).
      # but the nCycle() reactive doesn't work in place of 1:6
      lapply(1:6, function(j) {
        output[[paste0('outCiclo',j)]] &lt;- renderTable({
          subset(df(), ciclo==j)
        })
      })
      
    })
  }
  
  #------------------------------------------------------
  
  ui &lt;- dashboardPage(
    dashboardHeader(title = &quot;Teste Módulo TabBox Dinâmico&quot;),
    dashboardSidebar(
      sidebarMenu(
        menuItem('Ciclo e viveiro',tabName = 'box_din')
      )
    ),
    dashboardBody(
      tabItems(
        tabItem(tabName='box_din',
                fileInput(inputId = &quot;upload&quot;,label = &quot;Carregue seu arquivo&quot;, accept = c(&quot;.xlsx&quot;)),
                dashMenuUI('tabRender')
        )
      )
    )
    
  )
  
  server &lt;- function(input, output, session) {
    dados &lt;- reactive({
      req(input$upload)
      file &lt;- input$upload
      ext &lt;- tools::file_ext(file$datapath)
      req(file)
      validate(need(ext == &quot;xlsx&quot;, &quot;Por gentileza insira um arquivo de Excel (extensão .xlsx)&quot;))
      df &lt;- read.xlsx(file$datapath,sheet = 1)
      df
    })
    # Ciclo output
    dashMenuServer('tabRender',dados)
    
    
  }
  
  shinyApp(ui, server)
  </code></pre>
  <p>When running the first session of the script note that you get an excel file (.xlsx) in your Working Directory, it is the simulated data to import into the app. The problem is that the <code>1:6</code> sequence is fixed and doesn't vary depending on the data (the cycles above 6 are not rendered in the panels), when I replace <code>1:6</code> with <code>nCiclo()</code> (try to test for yourself) (it is found in the server module) doesn't work.</p>
  <p><em>I'm not sure if I made myself clear or if the English are understandable, but I thank you for taking the time to read the problem and help in my learning.</em></p>