Dropdown do not update client side

Hi,
I am trying to update a drop down when I load a new csv.
The data is correctly loaded and I can use it but the front does not refresh it :

# -*- coding: utf-8 -*-
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output, State

import pandas as pd

import base64
import io
import json

app = dash.Dash()

app.layout = html.Div([
    dcc.Store(id='dfs', storage_type='session'),
    dcc.Store(id='dfcolumns', storage_type='session'),
    dcc.Upload(
        id='upload-data',
        children=html.Div([
            'drag and drop or ',
            html.A('Click')
        ]), multiple=False,
        style={
            'width': '90%',
            'height': '400px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'center',
            'margin': '10px'
        }
    ),
    html.Div([
        # Feature Selector 1
        html.Div([
            dcc.Dropdown(
                id='graph-dropdown-1',
                clearable=False
                )
            ], style={
                'width': '70%',
                'margin-left': 'auto',
                'margin-right': 'auto',
            }
        )
    ])])

@app.callback([Output('graph-dropdown-1', "value")],
              [Input('graph-dropdown-1', "options")])
def update_drop_value(options):
    print("update_drop_value")
    if options:
        return [options[0]["value"]]
    return [0]

@app.callback(Output('graph-dropdown-1', "options"), [Input('dfcolumns', 'data')])
def refresh_graph_dropdown(data):
    print("refresh_graph_dropdown")
    if data:
        return [{'label': i, 'value': i} for i in data[1:]]
    return

def parse_contents(contents, filename, date):
    content_type, content_string = contents.split(',')

    decoded = base64.b64decode(content_string)
    try:
        if '.csv' in filename:
            try:
                df = pd.read_csv(
                    io.StringIO(decoded.decode('cp1252')),low_memory=False)
            except:
                df = pd.read_csv(
                    io.StringIO(decoded.decode('utf-8')),low_memory=False)
        elif '.xls' in filename:
            df = pd.read_excel(io.BytesIO(decoded))
    except Exception as e:
        print(e)
        return 'There was an error processing this file.'
    return df


@app.callback([Output('dfs', 'data'),
               Output('dfcolumns', 'data')],
              [Input('upload-data', 'contents')],
              [State('upload-data', 'filename'),
               State('upload-data', 'last_modified')])
def update_output(contents, names, dates):
    print("update_output")
    if contents is not None:
        children = parse_contents(contents, names, dates)
        if children is not None:
            jschildren = children.to_json()
            tmp2 = children.columns.values.tolist()
            jschildren = json.loads(jschildren)
            return jschildren, tmp2
    return {}, []

if __name__ == '__main__':
    app.run_server(debug=False, port=80)

and the csv is here if you want :

,CODE_ID,Number
0,742608,6.0
1,388219,14.0
2,251087,2.0
3,441845,114.0
4,447842,114.0
5,443841,114.0
6,471844,114.0
7,441543,114.0
8,471848,114.0
9,443847,114.0
10,441649,114.0

I run it on windows.
Thank you,

I slightly modified your code (search code for no_update) and all appears to work ok. Due to Dash invoking all callbacks at runtime, I think you were returning values that were causing issues elsewhere (when running your code initially, I received cannot find length of Noneerrors.

import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output, State
from dash.dash import no_update

import pandas as pd

import base64
import io
import json

app = dash.Dash()

app.layout = html.Div([
    dcc.Store(id='dfs', storage_type='session'),
    dcc.Store(id='dfcolumns', storage_type='session'),
    dcc.Upload(
        id='upload-data',
        children=html.Div([
            'drag and drop or ',
            html.A('Click')
        ]), multiple=False,
        style={
            'width': '90%',
            'height': '400px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'center',
            'margin': '10px'
        }
    ),
    html.Div([
        # Feature Selector 1
        html.Div([
            dcc.Dropdown(
                id='graph-dropdown-1',
                clearable=False
            )
        ], style={
            'width': '70%',
            'margin-left': 'auto',
            'margin-right': 'auto',
        }
        )
    ])])


@app.callback([Output('graph-dropdown-1', "value")],
              [Input('graph-dropdown-1', "options")])
def update_drop_value(options):
    print("update_drop_value")
    if options:
        return [options[0]["value"]]
    return no_update


@app.callback(Output('graph-dropdown-1', "options"), [Input('dfcolumns', 'data')])
def refresh_graph_dropdown(data):
    print("refresh_graph_dropdown")
    if data:
        return [{'label': i, 'value': i} for i in data[1:]]
    return no_update


def parse_contents(contents, filename, date):
    content_type, content_string = contents.split(',')

    decoded = base64.b64decode(content_string)
    try:
        if '.csv' in filename:
            try:
                df = pd.read_csv(
                    io.StringIO(decoded.decode('cp1252')), low_memory=False)
            except:
                df = pd.read_csv(
                    io.StringIO(decoded.decode('utf-8')), low_memory=False)
        elif '.xls' in filename:
            df = pd.read_excel(io.BytesIO(decoded))
    except Exception as e:
        print(e)
        return 'There was an error processing this file.'
    return df


@app.callback([Output('dfs', 'data'),
               Output('dfcolumns', 'data')],
              [Input('upload-data', 'contents')],
              [State('upload-data', 'filename'),
               State('upload-data', 'last_modified')])
def update_output(contents, names, dates):
    print("update_output")
    if contents is not None:
        children = parse_contents(contents, names, dates)
        if children is not None:
            jschildren = children.to_json()
            tmp2 = children.columns.values.tolist()
            jschildren = json.loads(jschildren)
            return jschildren, tmp2
    return no_update, no_update


if __name__ == '__main__':
    app.run_server(debug=True)

1 Like

Thank you very much, this was really helpful.