Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a function to directly retrieve component property values in callbacks #2971

Open
insistence opened this issue Aug 29, 2024 · 8 comments
Labels
feature something new P3 not needed for current cycle

Comments

@insistence
Copy link
Contributor

For example, I currently have a dcc.Store component in the application. The Store component stores the data that is required for most callbacks. In the current application, I have to add the Store component to the State in each callback.
Just like below

@app.callback(
    Output(...),
    Input(...),
    State('store', 'data')
)
def callback1(...):
    ...

@app.callback(
    Output(...),
    Input(...),
    State('store', 'data')
)
def callback2(...):
    ...

@app.callback(
    Output(...),
    Input(...),
    State('store', 'data')
)
def callback3(...):
    ...

If there is a get_props function, I can encapsulate a universal function that directly retrieves the data of the Store component for processing, without the need to retrieve the data of the Store component through the State in each callback.
Just like below

def global_deal_func():
    stroe_data = dash.get_props('store', 'data')
    ...


@app.callback(
    Output(...),
    Input(...)
)
def callback1(...):
    global_deal_func()
    ...

@app.callback(
    Output(...),
    Input(...)
)
def callback2(...):
    global_deal_func()
    ...

@app.callback(
    Output(...),
    Input(...)
)
def callback3(...):
    global_deal_func()
    ...

This is just a tentative feature request, perhaps there will be a better solution, thank you very much.

@AnnMarieW
Copy link
Collaborator

Thanks for the suggestion, however I wouldn’t recommend this feature. It’s just a different way to do it rather than a better way .

@insistence
Copy link
Contributor Author

insistence commented Aug 30, 2024

Sorry, I don't understand where you're not suggesting a better approach. Could you please explain it in detail? From my perspective, I think this approach can help save a lot of callback orchestration, especially when there are thousands of callbacks. Thanks!

@aGitForEveryone
Copy link
Contributor

aGitForEveryone commented Aug 30, 2024

Currently, you need 1 line for adding the State, and you need to add the parameter to the list of input parameters of the callback.

In your approach, you add 1 line inside the callback function body for retrieving the value.

Comparing both approaches it seems tits for tats. An alternative way for retrieving data, but is it necessarily better? In the current way, it is clear from the callback signature what data the callback requires. In your suggestion, you add an extra layer of obfuscation. Also I believe that this way of retrieving data is invisible for callback parsers, for example when analyzing the callback chain. Furthermore, the amount of code you have to write to retrieve the data is about the same in both ways. Also in your suggestion you have to add the function call in each of your callbacks.

So, I agree with Ann Marie here, I am not (yet) seeing the added value.

@insistence
Copy link
Contributor Author

Currently, you need 1 line for adding the State, and you need to add the parameter to the list of input parameters of the callback.

In you approach, you add 1 line inside the callback function body for retrieving the value.

Comparing both approaches it seems tits for tats. An alternative way for retrieving data, but is it necessarily better? In the current way, it is clear from the callback signature what data the callback requires. In your suggestion, you add an extra layer of obfuscation. Also I believe that this way of retrieving data is invisible for callback parsers, for example when analyzing the callback chain. Furthermore, the amount of code you have to write to retrieve the data is about the same in both ways. Also in your suggestion you have to add the function call in each of your callbacks.

So, I agree with Ann Marie here, I am not (yet) seeing the added value.

current approach

def global_deal_func(store_data):
    deal(store_data)
    ...

@app.callback(
    Output(...),
    Input(...),
    State('store', 'data')
)
def callback1(..., store_data):
    global_deal_func(store_data)
    ...

@app.callback(
    Output(...),
    Input(...),
    State('store', 'data')
)
def callback2(..., store_data):
    global_deal_func(store_data)
    ...

@app.callback(
    Output(...),
    Input(...),
    State('store', 'data')
)
def callback3(..., store_data):
    global_deal_func(store_data)
    ...

feature request approach

def global_deal_func():
    stroe_data = dash.get_props('store', 'data')
    deal(store_data)
    ...


@app.callback(
    Output(...),
    Input(...)
)
def callback1(...):
    global_deal_func()
    ...

@app.callback(
    Output(...),
    Input(...)
)
def callback2(...):
    global_deal_func()
    ...

@app.callback(
    Output(...),
    Input(...)
)
def callback3(...):
    global_deal_func()
    ...

Thank you for your explanation. I have updated the example code. In both ways, the global_deal_func function is required. In fact, it reduces the number of state orchestration. I agree with your point that the callback role is not clear enough. I just hope to provide another way to deal with this issue. When faced with a large number of callbacks, I really don't want to assign the same State role in every callback. If you can retrieve component property values by writing code only once, it feels quite good.

@insistence
Copy link
Contributor Author

@T4rk1n Excuse me, may I know your opinion?

@gvwilson gvwilson changed the title [Feature Request] Add a function to directly retrieve component property values in callbacks Add a function to directly retrieve component property values in callbacks Sep 3, 2024
@gvwilson gvwilson added feature something new P3 not needed for current cycle labels Sep 3, 2024
@T4rk1n
Copy link
Contributor

T4rk1n commented Sep 5, 2024

It would make sense if the callbacks were async based, so only for background callbacks that takes a longer times you might want the latest values after running for a while. The implementation would be kinda slowish, included in the request pooling loop.

For regular callbacks there is no way to make it work with a single request.

@insistence
Copy link
Contributor Author

It would make sense if the callbacks were async based, so only for background callbacks that takes a longer times you might want the latest values after running for a while. The implementation would be kinda slowish, included in the request pooling loop.

For regular callbacks there is no way to make it work with a single request.

Thank you for your detailed answer. If it can be implemented under limited conditions, I think it would still be a great feature. 😄

@deadkex
Copy link

deadkex commented Sep 12, 2024

You could try patching the app.callback function to always take the Store as last Input

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new P3 not needed for current cycle
Projects
None yet
Development

No branches or pull requests

6 participants