Repository: plotly/dash
File: dash-renderer/src/actions/index.js (JavaScript)

Code before:
}

function handleClientside(clientside_function, payload) {
    const dc = (window.dash_clientside = window.dash_clientside || {});
    if (!dc.no_update) {
        Object.defineProperty(dc, 'no_update', {
            value: {description: 'Return to prevent updating an Output.'},
            writable: false,
        });

        Object.defineProperty(dc, 'PreventUpdate', {
            value: {description: 'Throw to prevent updating all Outputs.'},
            writable: false,
        });
    }

    const {inputs, outputs, state} = payload;

    let returnValue;

    try {
        // setup callback context
        const input_dict = inputsToDict(inputs);
        dc.callback_context = {};
        if (payload.changedPropIds.length === 0) {
            dc.callback_context.triggered = [{prop_id: '.', value: null}];
        } else {
            dc.callback_context.triggered = payload.changedPropIds.map(
                prop_id => ({prop_id: prop_id, value: input_dict[prop_id]})
            );
        }
        dc.callback_context.inputs_list = inputs;
        dc.callback_context.inputs = input_dict;
        dc.callback_context.states_list = state;
        dc.callback_context.states = inputsToDict(state);

        const {namespace, function_name} = clientside_function;
        let args = inputs.map(getVals);
        if (state) {
            args = concat(args, state.map(getVals));
        }
        returnValue = dc[namespace][function_name](...args);

        delete dc.callback_context;
    } catch (e) {
        if (e === dc.PreventUpdate) {
            return {};
        }
        throw e;
    }


Review comment (suggestion):
I don't think we want this dummy value on the client side. On the server it's there for backward compatibility as versions before 1.11 would always have at least one entry in `triggered` (and in fact almost always had exactly one entry) so people were in the habit of just looking at `triggered[0]["prop_id"]`. In JS there's no such history to work around. Also in Python we have the flexibility to make this length-1 array [look falsy](https://github.com/plotly/dash/blob/439e13b673e8e8f3d4223e905d44c08c9f11eef2/dash/_callback_context.py#L21) which we can't do in JS.

Code after:
    }
    return inputs;
}

function handleClientside(clientside_function, payload) {
    const dc = (window.dash_clientside = window.dash_clientside || {});
    if (!dc.no_update) {
        Object.defineProperty(dc, 'no_update', {
            value: {description: 'Return to prevent updating an Output.'},
            writable: false,
        });

        Object.defineProperty(dc, 'PreventUpdate', {
            value: {description: 'Throw to prevent updating all Outputs.'},
            writable: false,
        });
    }

    const {inputs, outputs, state} = payload;

    let returnValue;

    try {
        // setup callback context
        const input_dict = inputsToDict(inputs);
        dc.callback_context = {};
        dc.callback_context.triggered = payload.changedPropIds.map(prop_id => ({
            prop_id: prop_id,
            value: input_dict[prop_id],
        }));
        dc.callback_context.inputs_list = inputs;
        dc.callback_context.inputs = input_dict;
        dc.callback_context.states_list = state;
        dc.callback_context.states = inputsToDict(state);

        const {namespace, function_name} = clientside_function;
        let args = inputs.map(getVals);
        if (state) {
            args = concat(args, state.map(getVals));
        }
        returnValue = dc[namespace][function_name](...args);

        delete dc.callback_context;
    } catch (e) {
        if (e === dc.PreventUpdate) {
            return {};
        }
        throw e;
    }

    if (type(returnValue) === 'Promise') {