Dash table doesn't get dynamically updated based on n_intervals. The callback function is triggered appropriately

Hey,

I have a dash mantine card which loads a df. The df should dynamically get updated based on n_intervals and a callback function. Here is the card:

dmc.GridCol(
    html.Div(
        dmc.Card(
            children=[
                dmc.CardSection(
                    children = [
                        dmc.Grid(
                            children=[
                                dmc.GridCol(
                                    dmc.Group(
                                        children=[
                                            dmc.ThemeIcon(
                                                DashIconify(icon="bxs:network-chart", width=30, height = 30),
                                                color="gray",
                                                variant="transparent",
                                            ),
                                            dmc.Text("Neighboring Transactions", fw=500),
                                        ],
                                        style={
                                            "margin-left": "10px", 
                                            "border": f"1px solid {dmc.DEFAULT_THEME['colors']['indigo'][4]}"
                                        } 
                                    ),
                                    span = 7,
                                ),
                            ],
                        ),
                    ],
                    withBorder=False,
                    py="xs"
                ),
                html.Div(
                    
                    style = {
                        "margin-left":"-6px",
                        "height": "382px",
                        "width":"434px",
                        'scrollbarWidth': 'thin',  # Make the scrollbar thinner
                        'scrollbarColor': 'gray',  # Set the scrollbar color
                        'scrollbarTrackColor': 'lightgray',  # Set the scrollbar track color
                        "border": f"1px solid {dmc.DEFAULT_THEME['colors']['indigo'][4]}",
                    },
                    children = [
                        dcc.Interval(id='neighboring-transactions-stream-interval', interval=1000),
                        dmc.ScrollArea(
                            style = {
                                "overflow":"auto",
                                "border": f"1px solid {dmc.DEFAULT_THEME['colors']['indigo'][4]}",
                                "height":"382px",
                                "width":"434px",
                            },
                            type = 'always',
                            # h=365, 
                            # w=420,
                            scrollbarSize = 8,
                            children = [
                                # dcc.Store(id='neighboring-transactions-stream-graph-store'),
                                html.Div(id='neighboring-transactions-stream'),
                                # dcc.Interval(id='neighboring-transactions-stream-interval', interval=1000)     
                                
                            ]   
                        ),
                        # dcc.Interval(id='neighboring-transactions-stream-interval', interval=1000),  # Update every 1 second
                    ]
                )    
            ],
            radius="md",
            style = {
                "backgroundColor": "rgba(37, 38, 43, 0.1)", 
                "box-shadow": "0 0 10px rgba(0, 0, 0, 0.3)", 
                "height":"48vh", 
                "border": f"1px solid {dmc.DEFAULT_THEME['colors']['indigo'][4]}"}
        ),
    ),
    span = 3
),

this is the callback function:

@callback(
      Output('neighboring-transactions-stream', 'children'),
      Input('neighboring-transactions-stream-interval', 'n_intervals'),            
      prevent_initial_call=True #'initial_duplicate'
  )
  def update_neighboring_transactions(n_intervals):

      # Transaction hashes.
      tx_hash_list = self.get_txids(self.get_state('prev_transaction_data'))

      # tx_hash_list = ['a', 'f', 'e', 'et']

      # Create a DataFrame with the list.
      if not tx_hash_list:

          df = pd.DataFrame()

      else:

          df = pd.DataFrame({
              'Index': range(1, len(tx_hash_list) + 1),  # Generate an index starting from 1
              'Transaction Hash': tx_hash_list  # Add the list of transaction hashes
          })

      print(df)

      data_table = dash_table.DataTable(
          id='neighboring-transactions-stream',
          columns=[{"name": i, "id": i} for i in df.columns],
          data=df.to_dict('records'),
          style_data_conditional=[
              {
                  'if': {'row_index': self.get_state('current_transaction_idx')},  # Default: Highlight the third row
                  'backgroundColor': 'rgba(0, 128, 128, 0.2)' #'rgba(172, 101, 181, 0.1)'
              },
              {
                  "if": {"state": "active"},  # Apply the style when the row is hovered
                  "backgroundColor": "rgba(41, 56, 55, 0.5)",
                  "border":'none'
              },
          ],
          style_cell={'backgroundColor': 'transparent', 'border': 'none', 'fontSize': '12px', 'fontWeight': 'bold', 'textAlign': 'left'}
      )
      
      # Display the DataFrame as a Dash DataTable.
      return [data_table]

what happens at the moment is that, initially the df is empty. So, the table shows nothing. When the df has values, the table is not updated in UI. I’ve checked and the callback function prints the updated df appropriately. It just doesn’t output it to the UI.

Any ideas?

Thank you!

Hi @and.man

I don’t see anything wrong with what you’ve posted. Can you include a complete minimal example with some sample data that can be run locally and reproduces the error?

1 Like

Hi @AnnMarieW, thank you for the reply :upside_down_face:

I’ve managed to solve the bug. The ids were conflicting. I had to change the id of the dash table in the callback function. Everything works fine now.

1 Like