How to trigger a server-side callback from within a javascript?

I want to trigger a server-side callback from within a javascript. Here is a simple javascript that changes the value of an input-component every second. However, this is not seen by dash and it doesn’t trigger the server-side callback. Any idea why is this? Or this is what it should be?

It should be noticed here that the value of the input component actually changes in each iteration in this loop. This can be shown in the browser and also when I console.log the value before and after assignment. However, the dash server-side callback is not triggered at all.

I also tried to add dcc.interval to trigger the server-side callback and State the input component. However, the value of the input component does not change from the initial value although both the javascript and browser show that the value is changed every 1 second as instructed in the code below.

I really appreciate your inputs as I have been scratching my head all day.

window.dash_clientside.clientside = {
iterate_and_display: function(n_clicks, numbers) {
const numbersArray = JSON.parse(numbers);

    let inputComponent = document.getElementById('hidden-input');

    function updateInputValue(index) {
        if (index < numbersArray.length) {
            let number = numbersArray[index];
            console.log('number:', number);
            console.log('inputComponent Value Before:', inputComponent.value);
            inputComponent.value = `(${number})`;
            console.log('inputComponent Value After:', inputComponent.value);
            
            setTimeout(() => updateInputValue(index + 1), 1000);  // Wait 1 second before next number
        }
    }
    updateInputValue(0);  // Start the process
    return '';
}

};

Hello @tmoussa,

React is triggered by events, for this one to trigger the update and server side update, you’ll need to trigger the input event and or update event on the input.

If this doesn’t work, you’ll need to make the change in the react component.

You also know that you could use a clientside callback with the interval as the trigger and perform this same function that you have.

Thanks @jinnyzor for your quick response.
I tried to do so by;

var evt = new Event('input');
inputComponent.dispatchEvent(evt);

But, this doesn’t trigger the server-side callback.
When I console.log ‘evt’ it shows:

evt: 
Event {isTrusted: false, type: 'input', target: null, currentTarget: null, eventPhase: 0, …}
isTrusted: false
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget : null
defaultPrevented: false
eventPhase: 0
returnValue : true
srcElement: input#hidden-input.dash-input
target: input#hidden-input.dash-input
timeStamp: 10680.20000000298
type:"input"
[[Prototype]]: Event

And it looks like it is enough to trigger the server-side callback.

Here is an example of what I want to do:
I have a python function (ML model) and I want to iterate it over a range on inputs. And at each iteration, I want to display the output to the user while running. So, basically what I need is a ‘for loop’ inside the server-side callback. Apparently this is not applicable as once I return any value in the for-loop it ends the callback. So, I decided to use the javascript to update the value of the input component in a for-loop and this input value shall trigger the server-side callback to run my ML function and display the output. Then, I wait until this output is displayed then the javascript update the input value again and so on.
So, basically it is displaying the incremental output while running.
Hope this clarifies what I want to achieve here.

Maybe this will help you :slight_smile:

EventListener from dash_extensions could also be useful here.

1 Like