How to convert a 'NoneType' object I get from a Checklist to a list or int32?

Can’t manage to make my callbacks to work with dash_table!

I have 2 filters applying to the data that will show in datatable. They both show just fine but the callback isn’t working.

dcc.Checklist( id = 'Tramos', options=[
                                {'label': 'Tramo 1   ', 'value': '1'},
                                {'label': 'Tramo 2   ', 'value': '2'},
                                {'label': 'Tramo 3   ', 'value': '3'}],
                    value=['1','2','3'],
                    labelStyle={'display': 'inline-block'})

    group0 = ['All']
    group1 = map_data['Tipo'].unique()
    group = np.concatenate([group0, group1])
    Tipo_Options = [{'label': str(item), 'value': str(item)} for item in group]

    Tramo1 = map_data['Tramo'].unique()
    Tramo_Options = [{'label': str(item), 'value': str(item)} for item in Tramo1]


    dcc.Dropdown(
                             id='Tipos2',
                             options= Tipo_Options,
                             multi=True,
                             value= group1)

and in the callback I have:

@app.callback(
    Output('datatable', 'rows'),
    [dash.dependencies.Input('Tramos', 'values'),
    dash.dependencies.Input('Tipos2', 'value')])

def update_selected_rows(tramos, tipos2):
    map_aux = map_data.copy()
    map_aux = map_aux[map_aux['Tramo'].isin(tramos)]
    map_aux = map_aux[map_aux['Tipo'].isin(tipos2)]
    rows = map_aux.to_dict('records')
    return rows

TypeError: only list-like objects are allowed to be passed to isin(), you passed a [NoneType]
I’ve tryed to change the function from isin() to queries but it gives me other error.

    def update_selected_rows(tramos, tipos2):
        map_aux = map_data.copy()
        map_aux1 = pd.DataFrame(columns=['Nome','PK','Lat','Lon','Tipo','Tramo'])
        map_aux2 = pd.DataFrame(columns=['Nome','PK','Lat','Lon','Tipo','Tramo'])

        for tramo in tramos:
            map_aux = map_aux.query('Tramo'==tramo)
            map_aux1 = pd.concatenate([map_aux1, map_aux])

        for tipo in tipos2:
            map_aux1 = map_aux1.query('Tipo'==tipo)
            map_aux2 = pd.concatenate([map_aux2, map_aux1])
            
        rows = map_aux2.to_dict('records')
        return rows

TypeError: ‘NoneType’ object is not iterable

How can I convert the information from the checklist and the dropdown to be a list or an integer instead of a NoneType??

UPDATE IT’s SOLVED

I manage to solve my problem by changing my callback. The problem wasn’t in the checkbox or dropdown elements but in my table.
Before I was returning rows of a table and I had a Div with a dcc.Graph element inside that received that info and filtered the dash_table_experiments.

Changing to dash_table changed the element behaviour. So my way of solving it was, instead of returning rows, I return the dcc.Graph element to my html.Div

So I have a:

html.Div(id='datatable')

and my callback:

@app.callback(
    Output('datatable', 'children'),
    [Input('Tramos', 'value'),
    Input('Tipos2', 'value')])

def update_selected_rows(tramos, tipos2):
    map_aux = map_data.copy()
    map_aux = map_aux[map_aux['Tramo'].isin(tramos)]
    map_aux = map_aux[map_aux['Tipo'].isin(tipos2)]
    return dt.DataTable(id='FilteredTable',
                 columns = columns,
                 data = map_aux.to_dict('records'),
                 editable = False,
                 #filter_action='native',
                 sort_action='native',
                 row_selectable='multi',
                 row_deletable=False,
                 virtualization=True,
                 page_action='none',
                 selected_rows=[]
                 )

I hope this helps someone in the future.

What I suspect is happening is this error is caused during page-load, where Dash executes the callbacks. The NoneType is the current value of your inputs.

I get around this problem by error checking my inputs at the start of each callback, utilizing dash.callback_context (see https://dash.plot.ly/faqs and the question Q: How do I determine which Input has changed?)

In your callback, define ctx as:
ctx = dash.callback_context

Then, the following will tell you which input triggered the callback:
triggered = ctx.triggered[0]['prop_id'].split('.')[0]

You could then return no_update if their input was the callback trigger.

1 Like

Hi @flyingcujo, I think I’m not following you, newbie here! :crazy_face:.

The NoneType is the current value of my inputs, and I get them by dcc.Checklist and dcc.Dropdown… so until here I understand you.
image

What I don’t really get is why error checking my inputs would change their data type so that could actually work… Sorry if I’m doing a dumb question…!!

And another thing that has me confused is that this code worked with dash 0.40.00 and now it doesn’t. A had to change from dash_table_experiments to dash_table and everything just stopped working. :frowning:

Error checking will prevent you from reaching the code where the error is occurring. When a user selects a value from either your dropdown or checklist, the value assoc. with it will not be NoneType. NoneType indicates the value is not set, i.e. empty, null, etc.

Also, there were huge differences in dash_table_experiments and dash_table so I’m not surprised it worked before migration to dash_table. I had similar headaches.

2 Likes

Thank you so much! I’ll try it…
Yeap…headaches! :slightly_smiling_face:

1 Like