title: Add rows to the datatable-Error loading dependencies
body: <p>I want to create an app that a user can upload CSV files and it will show a data table that the user can edit, add columns and add rows. There are also two dropdowns that contain the value of the columns of the data table. But I get Error loading dependencies after I run the code. Can anyone teach me how to fix this error?</p>
  
  <p>Below is the code:</p>
  
  <pre><code>import base64
  import io
  import dash
  from dash.dependencies import Input, Output, State
  import dash_core_components as dcc
  import dash_html_components as html
  import dash_table
  import pandas as pd
  from dash.exceptions import PreventUpdate
  
  external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
  
  app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
  app.config.suppress_callback_exceptions = True
  app.layout = html.Div([
      dcc.Upload(
          id='datatable-upload',
          children=html.Div([
              'Drag and Drop or ',
              html.A('Select Files')
          ]),
          style={
              'width': '100%', 'height': '60px', 'lineHeight': '60px',
              'borderWidth': '1px', 'borderStyle': 'dashed',
              'borderRadius': '5px', 'textAlign': 'center', 'margin': '10px'
          },
      ),
      html.Div([
          dcc.Input(
              id='adding-rows-name',
              placeholder='Enter a column name...',
              value='',
              style={'padding': 10}
          ),
          html.Button('Add Column', id='adding-rows-button', n_clicks=0)
      ], style={'height': 50}),
  
      html.Div(id='output-data-upload'),
      html.Button('Add Row', id='editing-rows-button', n_clicks=0),
      dcc.Dropdown(
          id='data_selector1',
          options=[       
              {'label': '', 'value': ''}
          ],
           value=[]
      ),
     dcc.Dropdown(
          id='data_selector2',
          options=[       
              {'label': '', 'value': ''}
          ],         
           value=[]
      ),
  ])
  
  
  def parse_contents(contents, filename):
      content_type, content_string = contents.split(',')
      decoded = base64.b64decode(content_string)
      if 'csv' in filename:
          # Assume that the user uploaded a CSV file
          return pd.read_csv(
              io.StringIO(decoded.decode('utf-8')))
      elif 'xls' in filename:
          # Assume that the user uploaded an excel file
          return pd.read_excel(io.BytesIO(decoded))
  
  
  @app.callback(Output('output-data-upload', 'children'),
                [Input('datatable-upload', 'contents')],
                [State('datatable-upload', 'filename')])
  def update_output(contents, filename):
      if contents is None:
          return []
      df = parse_contents(contents, filename)
      return html.Div([
          dash_table.DataTable(
              id='table',
              style_data={
                       'whiteSpace': 'normal',
                       'height': 'auto'
                       },
               style_table={'overflowX': 'scroll',
                            'maxHeight': '300',
                            'overflowY': 'scroll'},
               style_cell={                     
                       'minWidth': '150px', 'maxWidth': '180px',
                       'whiteSpace': 'normal',
                       'textAlign': 'left'
                  },
              style_header={                   
                      'fontWeight': 'bold',                   
                                      },            
              fixed_rows={ 'headers': True, 'data': 0 },           
              columns=[{"name": i, "id": i, 'deletable': True, 'renamable': True} for i in df.columns],
              data=df.to_dict("records"),                             
              row_deletable=True,
              filter_action="native",
              sort_action="native",
              sort_mode='multi',
              editable=True,
          )
      ])
  
  #The code will work if I remove this function     
  @app.callback(                   
      Output('table', 'data'),
      [Input('editing-rows-button', 'n_clicks')],
      [State('table', 'data'),
       State('table', 'columns')])
  def add_row(n_clicks, rows, columns):
      if n_clicks &gt; 0:
          rows.append({i['id']: '' for i in columns})
      return rows
  
  @app.callback(
      Output('table', 'columns'),
      [Input('adding-rows-button', 'n_clicks')],
      [State('adding-rows-name', 'value'),
       State('table', 'columns')])
  def update_columns(n_clicks, value, existing_columns):
      if n_clicks &gt; 0:
          existing_columns.append({
              'id': value, 'name': value,
              'renamable': True, 'deletable': True
          })
      return existing_columns
  
  @app.callback(Output('data_selector1', 'options'),
                [Input('table', 'data')])
  def update_dropdown(rows):
      if rows is None:
          raise PreventUpdate
      df = pd.DataFrame(rows)
      print('updating menus')
      columns = df.columns
      col_labels = [{'label': k, 'value': k} for k in columns]
      return col_labels
  
  @app.callback(Output('data_selector2', 'options'),
                [Input('table', 'data')])
  def update_dropdown2(rows):
      if rows is None:
          raise PreventUpdate
      df = pd.DataFrame(rows)
      print('updating menus')
      columns = df.columns
      col_labels = [{'label': k, 'value': k} for k in columns]
      return col_labels
  
  
  if __name__ == '__main__':
      app.run_server(debug=False)
  </code></pre>
  
  <p>The code will work if I remove the add rows to the data table function.</p>