Dash Web App: Adding block of code messes up the entire app

I am making a web app using python and dash. Everything seems to go well except when I add the last callback function add_new_parcel_submit to update my database. When I add this, the login page is not showing and the navbar is not responding to change links.

Here is my index.py:

app.layout = html.Div(
    [
        # Location Variable -- contains details about the url
        dcc.Location(id='url', refresh=True),
        
        # LOGIN DATA
        # 1) logout indicator, storage_type='session' means that data will be retained
        #  until browser/tab is closed (vs clearing data upon refresh)
        dcc.Store(id='sessionlogout', data=True, storage_type='session'),
        
        # 2) current_user_id -- stores user_id
        dcc.Store(id='currentuserid', data=-1, storage_type='session'),
        
        # 3) currentrole -- stores the role
        # we will not use them but if you have roles, you can use it
        dcc.Store(id='currentrole', data=-1, storage_type='session'),

        # Adding the navbar
        html.Div(
            cm.navbar,
            id='navbar_div'
        ),

        # Page Content -- Div that contains page layout
        html.Div(id='page-content', style=CONTENT_STYLE),

    ]
)


@app.callback(
    [
        Output('page-content', 'children'),
        Output('sessionlogout', 'data'),
        Output('navbar_div', 'className'),
    ],
    [
        # If the path (i.e. part after the website name; 
        # in url = youtube.com/watch, path = '/watch') changes, 
        # the callback is triggered
        Input('url', 'pathname')
    ],
    [
        State('sessionlogout', 'data'),
        State('currentuserid', 'data'),
    ]
)


def displaypage (pathname,
                 sessionlogout, userid):
    ctx = dash.callback_context
    if ctx.triggered:
        eventid = ctx.triggered[0]['prop_id'].split('.')[0]
        
    else:
        raise PreventUpdate
    
    
    if eventid == 'url':
        if userid < 0: # if logged out
            if pathname == '/':
                returnlayout = login.layout
            elif pathname == '/signup':
                returnlayout = signup.layout
            else:
                returnlayout = '404: request not found'
            
        else:    
            if pathname == '/logout':
                returnlayout = login.layout
                sessionlogout = True
                
            elif pathname == '/' or pathname == '/home':
                # From the imported module 'home', we get the layout variable
                returnlayout = home.layout

            elif pathname == '/parcel_management':
                returnlayout = parcel_management.layout

            elif pathname == '/parcel_management/add_new_group':
                returnlayout = add_new_parcel_group.layout
            elif pathname == '/parcel_management/add_new_parcel':
                returnlayout = add_new_parcel.layout
            elif pathname == '/parcel_management/update_parcel_group':
                returnlayout = update_parcel_group.layout
            elif pathname == '/parcel_management/update_parcel_status':
                returnlayout = update_parcel_status.layout

            elif pathname == '/dashboard':
                returnlayout = dashboard.layout

            elif pathname == '/parcel_forecast':
                returnlayout = parcel_forecast.layout

            else:
                returnlayout = '404: request not found'
                
        # decide sessionlogout value
        logout_conditions = [
            pathname in ['/', '/logout'],
            userid == -1,
            not userid
        ]
        sessionlogout = any(logout_conditions)
        
        # hide navbar if logged-out; else, set class/style to default
        navbar_classname = 'd-none' if sessionlogout else ''
        
        return [returnlayout, sessionlogout, navbar_classname]
    else:
        raise PreventUpdate


if __name__ == '__main__':
    webbrowser.open('http://127.0.0.1:8050/', new=0, autoraise=True)
    app.run_server(debug=False)


here is my login.py

from app import app
from apps import dbconnect as db

layout = html.Div(
    [
        html.H2('Please Login'),
        html.Hr(),
        dbc.Alert('Username or password is incorrect.', color="danger", id='login_alert',
                  is_open=False),
        dbc.Row(
            [
                dbc.Label("Username", width=2),
                dbc.Col(
                    dbc.Input(
                        type="text", id="login_username", placeholder="Enter username"
                    ),
                    width=6,
                ),
            ],
            className="mb-3",
        ),
        dbc.Row(
            [
                dbc.Label("Password", width=2),
                dbc.Col(
                    dbc.Input(
                        type="password", id="login_password", placeholder="Enter password"
                    ),
                    width=6,
                ),
            ],
            className="mb-3",
        ),
        dbc.Button('Login', color="secondary", id='login_loginbtn'),
        html.Hr(),
        html.A('Signup Now!', href='/signup'),
    ]
)


@app.callback(
    [
        Output('login_alert', 'is_open'),
        Output('currentuserid', 'data'),
    ],
    [
        Input('login_loginbtn', 'n_clicks'), # begin login query via button click
        Input('sessionlogout', 'modified_timestamp'), # reset session userid to -1 if logged out
    ],
    [
        State('login_username', 'value'),
        State('login_password', 'value'),   
        State('sessionlogout', 'data'),
        State('currentuserid', 'data'), 
        State('url', 'pathname'), 
    ]
)
def loginprocess(loginbtn, sessionlogout_time,
                 
                 username, password,
                 sessionlogout, currentuserid,
                 pathname):
    
    ctx = callback_context
    
    if ctx.triggered:
        openalert = False
        eventid = ctx.triggered[0]['prop_id'].split('.')[0]
    else:
        raise PreventUpdate
    
    
    if eventid == 'login_loginbtn': # trigger for login process
    
        if loginbtn and username and password:
            sql = """SELECT user_id
            FROM users
            WHERE 
                user_name = %s AND
                user_password = %s AND
                NOT user_delete_ind"""
            
            # we match the encrypted input to the encrypted password in the db
            encrypt_string = lambda string: hashlib.sha256(string.encode('utf-8')).hexdigest() 
            
            values = [username, encrypt_string(password)]
            cols = ['userid']
            df = db.querydatafromdatabase(sql, values, cols)
            
            if df.shape[0]: # if query returns rows
                currentuserid = df['userid'][0]
            else:
                currentuserid = -1
                openalert = True
                
    elif eventid == 'sessionlogout' and pathname == '/logout': # reset the userid if logged out
        currentuserid = -1
        
    else:
        raise PreventUpdate
    
    return [openalert, currentuserid]


@app.callback(
    [
        Output('url', 'pathname'),
    ],
    [
        Input('currentuserid', 'modified_timestamp'),
    ],
    [
        State('currentuserid', 'data'), 
    ]
)
def routelogin(logintime, userid):
    ctx = callback_context
    if ctx.triggered:
        if userid > 0:
            url = '/home'
        else:
            url = '/'
    else:
        raise PreventUpdate
    return [url]

here is my update_parcep_status.py

dash.register_page(__name__, path='/')


layout = dbc.Container([
    html.H1("Update Parcel Status"),
    dbc.Form([
        dbc.CardGroup([  # Use CardGroup instead of FormGroup
            dbc.Label("Parcel ID*"),
            dcc.Dropdown(
                id='parcel-id',
                placeholder="Select Status",
                style={'width': '100%'} 
            ),
        ]),
        dbc.CardGroup([  # Use CardGroup instead of FormGroup
            dbc.Label("Status*"),
            dcc.Dropdown(
                id='status-id',
                placeholder="Select Status",
                style={'width': '100%'} 
            ),
        ]),
        dbc.CardGroup([  # Use CardGroup instead of FormGroup
            dbc.Label("Location"),
            dbc.Input(type="text", id="location"),
        ]),
        html.Br(),
        dbc.Button("Update Status", id="update-button", color="primary"),
        html.Div(id='output-container-button'),  # Placeholder for callback output
    ]),
    dcc.Interval(
        id='interval-component',
        interval=60000,  # in milliseconds
        n_intervals=0
    )
], fluid=True)



@app.callback(
    Output('status-id', 'options'),
    [Input('interval-component', 'n_intervals')]
)
def update_status_options(n):
    print("Callback1")  # Debug statement to check if callback is triggered
    try:
        # Fetch data from the parcelstatus_mapping table
        query = """
            SELECT status_id, status_desc
            FROM parcelstatus_mapping;
        """
        df = db.querydatafromdatabase(query, values=[], dfcolumns=['status_id', 'status_desc'])
        # print (df)
        # Convert DataFrame to a list of dictionaries suitable for dropdown options
        options = [{'label': desc, 'value': str(status_id)} for status_id, desc in zip(df['status_id'], df['status_desc'])]


    except Exception as e:
        print(f"Error fetching data for status options: {e}")
        options = []

    return options



@app.callback(
    Output('parcel-id', 'options'),
    [Input('interval-component', 'n_intervals')]
)
def update_parcel_options(n):

    print("Callback2")  # Debug statement to check if callback is triggered
    try:
        # Fetch data from the parcel_status table

        # print('a')

        query = """
            SELECT parcel_id
            FROM parcel_status;
        """

        
        df = db.querydatafromdatabase(query, values=[], dfcolumns=['parcel_id'])

        # Convert DataFrame to a list of dictionaries suitable for dropdown options
        options = [{'label': str(parcel_id), 'value': str(parcel_id)} for parcel_id in df['parcel_id']]
    except Exception as e:
        print(f"Error fetching data for parcel options: {e}")
        options = []

    return options


@app.callback(
    Output('output-container-button', 'children'),
    [Input('update-button', 'n_clicks'),
     Input('url', 'pathname')],
    [State('parcel-id', 'value'),
     State('location', 'value')]

)
def add_new_parcel_submit(n_clicks, parcel_id, location, pathname):
    if pathname != '/parcel_management/update_parcel_status':
        raise PreventUpdate  # Callback only runs when URL matches '/parcel_management/update_parcel_status'

    if not n_clicks:
        raise PreventUpdate
    # return [html.Div([f"Parcel ID: {parcel_id}, Location: {location}"])]
    print("Callback triggered with n_clicks:", n_clicks)  # Debug statement to check if callback is triggered
    if not n_clicks:
        raise PreventUpdate

    alert_open = True
    alert_color = 'danger'
    alert_text = 'Failed to add new parcel.'
    modal_open = False

    if not all([parcel_id,  location]):
        alert_text = 'Check your inputs. Please fill in all the required fields.'
        print("Not all fields filled:", parcel_id,  location)  # Debug statement for incomplete fields
    else:
        try:
            # Constructing the SQL query
            sql = '''
                INSERT INTO parcel_status (parcel_id,  update_timestamp, location)
            '''
            # Adding the values to the values list
            values = [parcel_id, 1, datetime.now(), location]
            print("SQL values:", values)  # Debug statement for SQL values

            sql += ') VALUES (' + ', '.join(['%s'] * len(values)) + ')'
            print("SQL query:", sql)  # Debug statement for constructed SQL query
            
            # db.modifydatabase(sql, values)
            print("Database modification successful")  # Debug statement for successful database modification

            alert_open = True
            alert_color = 'success'
            alert_text = 'New parcel added successfully.'
            modal_open = True
        except Exception as e:
            alert_text = f'Failed to add new parcel: {str(e)}'
            print("Exception occurred:", e)  # Debug statement for exception

    return [html.Div(alert_text, className=f'alert alert-{alert_color}', role='alert'), modal_open]

I tried to check the ids and all seems to be correct. i tried to put the preventupdate for the
add_new_parcel_submit to only be called when in that app, but adding that callback still breaks the code. Can you help pls? I am stucked for days here huhu

New contributor

Acid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật