Download excel with multiple Input/State/Output - being called with wrong Input

I have The states below which are being called with Input(‘submit-button_table’, ‘n_clicks’)] button,

and the first 2 outputs are executed,

but the issue is that my 2nd input [Input(‘btn_xlsx’, ‘n_clicks’),

and the 3rd output Output(‘download-dataframe-xlsx’, ‘data’)], # download excel

are being called when I press on the 1st Input submit-button_table as well, altogether.

How to set my download excel Output to get called only when I press on Input(‘btn_xlsx’, ‘n_clicks’)

@app.callback(

[Output('table','columns'), # 1st Output, excel columns

 Output('table', 'data'), #2nd Output, excel table

Output('download-dataframe-xlsx', 'data')], #3rd Output, download 
#excel

[Input('btn_xlsx', 'n_clicks'), #2nd Input, click on download

Input('submit-button_table', 'n_clicks')], #1st Input, click submit 
#for the states below to call

[State('symbol', 'value'),

 State('yes_no', 'value'),

State('my_date_picker_table', 'start_date'),

State('my_date_picker_table', 'end_date'),

State('delete', 'value'),

State('percentage', 'value'),

State('points', 'value')],

prevent_initial_call=True,

)

Hi,

It is a bit difficult to understand your callback without its body (the function), so it is a good idea to add it so others can help you more easily.

That said, looking solely on the component names and props being updated, it seems to me that your callback intends to do two distinct tasks, namely:

  1. Update a table when “submit-button_table” is clicked.
  2. Download the table when “btn_xlsx” is clicked.

If that is the case, I would encourage you to split in two distinct callbacks, since this callback as-is will be triggered regardless the button is pressed. For the download callback, you can simply pass the table columns and data as State, unless you need the other State to modify the xlsx.

Otherwise, if you don’t want to split the callback in two for some reason, you can still use the callback context to get which button was pressed and conditionally skip the updates of some of the Outputs based on it, but this is a big overkill if your callback looks like what I imagine.

Hope this helps! :slightly_smiling_face:

2 Likes

Thank you for the reply, the body was too long to post.

I did exactly what you wrote, created a 2nd callback for;
2. Download the table when “btn_xlsx” is clicked.

With making the dataframe (table) calculated in the first callback global, so I can reference it any callback.

Glad it helped.

Just be careful with global variables in Dash. I strongly recommend reading the section Why Global Variables Will Break Your App in the docs: