Skip to content

[Feature Request] Inline clientside callbacks #956

Closed

Description

@alexcjohnson

Right now our clientside callbacks need to reference a separate file - typically loaded in via assets - where the functions are defined in a special namespace:

window.dash_clientside = Object.assign({}, window.dash_clientside, {
    large_params_function: function(largeValue1, largeValue2) {
        return someTransform(largeValue1, largeValue2);
    }
});

Then in the app you reference these functions by namespace and name:

app.clientside_callback(
    ClientsideFunction('clientside', 'large_params_function'),
    Output('out-component', 'value'),
    [Input('in-component1', 'value'), Input('in-component2', 'value')]
)

From a user standpoint, at least for simple functions it would be convenient to be able to provide the function just as a string with the callback definition. We would then package these up with some automatic namespace and naming, either as a separate endpoint or just a special case of _dash-component-suites, and reference it in the generated index alongside all the other scripts.

app.clientside_callback(
    """
    function(largeValue1, largeValue2) {
        return someTransform(largeValue1, largeValue2);
    }
    """,
    Output('out-component', 'value'),
    [Input('in-component1', 'value'), Input('in-component2', 'value')]
)

Activity

  1. jjaraalm commented on Oct 11, 2019

    @jjaraalm
    Contributor

    Taking this one step further, it would be great if we could use a transpiler like Transcrypt to write the callback in python then convert it to js, Then the API for clientside callbacks and server callbacks could be integrated like

    @app.callback(
        Output('out', 'value'),
        [Input('in', 'value')],
        clientside=True)
    def callback(input):
        return input in range(5)

    The simple and dumb way to do this would be to use inspect to dump the source to a temporary file, transpile it, then load and deploy the js. We would probably want to do some preprocessing on the source to make sure the callback is "simple."

    The entire global context probably shouldn't be included in the transpiling, but we could allow users to pass in a context so that calls like

    @app.callback(
        Output('out', 'value'),
        [Input('in', 'value')],
        clientside=True,
        context={'i': 4})
    def callback(input):
        return input in range(i)

    also work. In this case i is always a fixed constant, but this would be helpful if/when programatically generating callbacks.

  2. added this to the Dash v1.x milestone on Oct 11, 2019
  3. Marc-Andre-Rivet commented on Jan 14, 2020

    @Marc-Andre-Rivet
    Contributor

    @alexcjohnson Closing this as fixed. Let's open a new issue if there's a need for a follow up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions