Search code examples
pythoncallbackplotlyplotly-dashplotly-python

passing value from callback to callback in Plotly dash application


i have a dash application with a plotly graph i have two callbacks i want to get input from the user store it with dcc.store in the variable with id 'stkName-value' and call it in the other callback. I want to be able to get the user input and use it in the callback function update_graph_live how would i do this please help

from dash import Dash, dcc, html, Input, Output, callback, State
app = Dash()
app.layout = html.Div([
    
    dcc.Graph(id='graph'),
    dcc.Interval(
        id='interval',
        interval=inter,
        n_intervals=0,
      ),

    html.Div(dcc.Input(id='input-on-submit', type='text')),
    html.Button('Submit', id='submit-val', n_clicks=0),
    html.Div(id='container-button-basic',children='Enter a value and press submit'),

    dcc.Store(id='stkName-value')
    
    

])

@callback(
    Output('stkName-value', 'data'),
    Output('container-button-basic', 'children'),
    Input('submit-val', 'n_clicks'),
    State('input-on-submit', 'value'),
    prevent_initial_call=True
)

def update_output(n_clicks, value):
    value = str(value).upper() 
    if value in symbols:
        print('The input symbol was "{}" '.format(value))
        return str(value).upper(), str(value).upper()
    else:
        return 'The input symbol was '+str(value)+' is not accepted please try different symbol ', 'The input symbol was '+str(value)+' is not accepted please try different symbol '

@callback(Output('graph', 'figure'),
          Input('interval', 'n_intervals'))

def update_graph_live(n_intervals):
...
return figure
 

    Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2525, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1822, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1820, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1796, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
  File "/usr/local/lib/python3.9/site-packages/dash/dash.py", line 1224, in dispatch
    args_grouping = map_grouping(
  File "/usr/local/lib/python3.9/site-packages/dash/_grouping.py", line 124, in map_grouping
    return [map_grouping(fn, g) for g in grouping]
  File "/usr/local/lib/python3.9/site-packages/dash/_grouping.py", line 124, in <listcomp>
    return [map_grouping(fn, g) for g in grouping]
  File "/usr/local/lib/python3.9/site-packages/dash/_grouping.py", line 129, in map_grouping
    return fn(grouping)
  File "/usr/local/lib/python3.9/site-packages/dash/dash.py", line 1225, in <lambda>
    lambda ind: inputs_state[ind], inputs_state_indices
IndexError: list index out of range

when i add the the store value to the second callback i am getting this error only when i run it in google cloud but it runs fine on my local machine can some tell me what the issue is causing this?

Solution

  • You need to use a State() for the store in the second callback, just as for the 'input-on-submit' component value in the first callback :

    @callback(
        Output('graph', 'figure'),
        Input('interval', 'n_intervals'),
        State('stkName-value', 'data')
    )
    def update_graph_live(n_intervals, data):
        # ...
        return figure
    

    The function will still be triggered by the interval input, but it will receive the current store data as well.