'NoneType' object is not callable

Hello, I am trying to make a multi page app in dash, which get and modifies data in mongodb. While I run the app I get an ‘NoneType’ object is not callable , I think it’s because of the
cc variable in the @dash.clientside_callback ( Admin.py). Any help would be highly appreciated

App.py

import dash
from dash import html, dcc
import dash_bootstrap_components as dbc

app = dash.Dash(__name__, use_pages=True,suppress_callback_exceptions=True)


app.layout = html.Div(
    [
        # main app framework
        html.Div("Admin Page", style={'fontSize':50, 'textAlign':'center'}),
        html.Div([
            dcc.Link(page['name']+"  |  ", href=page['path'])
            for page in dash.page_registry.values()
        ]),
        html.Hr(),

        # content of each page
        dash.page_container
    ]
)


if __name__ == "__main__":
    app.run(debug=True)

Admin.py

import dash                                                     
from dash import html, dcc, Input, Output, State, dash_table
import pandas as pd                                            
import plotly.express as px
import pymongo                                                  
from bson.objectid import ObjectId
import dash_bootstrap_components as dbc

client = pymongo.MongoClient("mongodb+srv://HARSHA:123@cargoshipmanagementsyst.kgitmho.mongodb.net/?retryWrites=true&w=majority")
db = client["cargo"]

collection = db["Billing"]

dash.register_page(__name__,path='/')
layout = html.Div(children = [
    html.H1('ADMIN PAGE', style={'textAlign': 'center'}),
    # interval activated once/week or when page refreshed
    dcc.Interval(id='interval_db', interval=86400000 * 7, n_intervals=0),
    html.Div(id='mongo-datatable', children=[]),

    html.Div([
        html.Div(id='pie-graph', className='five columns'),
        html.Div(id='hist-graph', className='six columns'),
    ], className='row'),
    dcc.Store(id='changed-cell')
])

# Display Datatable with data from Mongo database
@dash.callback(Output('mongo-datatable', component_property='children'),
              Input('interval_db', component_property='n_intervals')
              )
def populate_datatable(n_intervals):
    # Convert the Collection (table) date to a pandas DataFrame
    df = pd.DataFrame(list(collection.find()))
    # Convert id from ObjectId to string so it can be read by DataTable
    df['_id'] = df['_id'].astype(str)
    print(df.head(20))

    return [
        dash_table.DataTable(
            id='our-table',
            data=df.to_dict('records'),
            columns=[{'id': p, 'name': p, 'editable': False} if p == '_id'
                     else {'id': p, 'name': p, 'editable': True}
                     for p in df],
        ),
    ]
# store the row id and column id of the cell that was updated
@dash.clientside_callback(
    """
    function (input,oldinput) {
        if (oldinput != null) {
            if(JSON.stringify(input) != JSON.stringify(oldinput)) {
                for (i in Object.keys(input)) {
                    newArray = Object.values(input[i])
                    oldArray = Object.values(oldinput[i])
                    if (JSON.stringify(newArray) != JSON.stringify(oldArray)) {
                        entNew = Object.entries(input[i])
                        entOld = Object.entries(oldinput[i])
                        for (const j in entNew) {
                            if (entNew[j][1] != entOld[j][1]) {
                                changeRef = [i, entNew[j][0]] 
                                break        
                            }
                        }
                    }
                }
            }
            return changeRef
        }
    }    
    """,
    Output('changed-cell', 'data'),
    Input('our-table', 'data'),
    State('our-table', 'data_previous')
)


# Update MongoDB and create the graphs
@dash.callback(
    Output("pie-graph", "children"),
    Output("hist-graph", "children"),
    Input("changed-cell", "data"),
    Input("our-table", "data"),
)

def update_d(cc,tabledata):
    if not cc:
        # Build the Plots
        pie_fig = px.pie(tabledata, values='No Of Containers', names='Container Type')
        hist_fig = px.bar(tabledata, x='Dimensions', y='Amount')
    else:
        print(f'changed cell: {cc}')
        print(f'Current DataTable: {tabledata}')
        x = int(cc[0])

        # update the external MongoDB
        row_id = tabledata[x]['Order_id']
        col_id = cc[1]
        new_cell_data = tabledata[x][col_id]
        collection.update_one({'Order_id': row_id},
                              {"$set": {col_id: new_cell_data}})
        # Operations guide - https://docs.mongodb.com/manual/crud/#update-operations

        pie_fig = px.pie(tabledata, values='No Of Containers', names='Container Type')
        hist_fig = px.px.bar(tabledata, x='Dimensions', y='Amount')

    return dcc.Graph(figure=pie_fig), dcc.Graph(figure=hist_fig)



Hi,

I did not dig too deep into this, but as you mentioned the variable cc I took a look at this part of your code. if I understand correctly, you want your callback function update_d to do different things depending on the triggering input.

If so, you could use callback_context to achieve this, as stated in here:

Another example::

@AIMPED
I couldn’t figure out how to use it

HI, what I am suggesting is, that you substitute this part of your code:

Using the callback_context in order to distinguish between the triggering Input. But as I said before, itis only a guess since you mentioned the variable cc in your initial post.

@AIMPED
Man, I tried reading it and implementing it. I just can’t get it to work, it keeps showing me the same error. I am relatively new to programming. Do you mind sharing me the fix with me?

The python code I shared should work in any computer

Hi @Gallad

dash does give you the line with the errorcode and that might give you an indication what went wrong. If you have found this error, it would be helpful you post it here as well.

One Variable in your code is of type None and you try to call a method/variable of this “Nonetype” Variable.

Best Regards