Search code examples
pythonbokeh

Clarification on bokeh's callback


A callback function in bokeh usually has three arguments: attr, old, and new as shown in this example in the documentation

def my_text_input_handler(attr, old, new):
    print("Previous label: " + old)
    print("Updated label: " + new)

text_input = TextInput(value="default", title="Label:")
text_input.on_change("value", my_text_input_handler)

My questions are:

  1. Why isn't attr used inside the body of the function my_text_input_handler? What (attr) is it actually?
  2. What is the parameter "value" in the method text_input.on_change("value"...)?
  3. After running the curdoc(), a text box with a value ("default") was displayed. I then changed that value ("default") to "test", nothing was printed out whilst I thought 2 sentences "Previous label: default" and "Updated label: test" would be produced.

Thank you.


Solution

  • From the docs:

    All widgets have an .on_change method that takes an attribute name and one or more event handlers as parameters. These handlers are expected to have the function signature, (attr, old, new), where attr refers to the changed attribute’s name, and old and new refer to the previous and updated values of the attribute.

    1. attr isn't used inside the body of the function my_text_input_handler because it doesn't rely on or do anything with the data. All of the callbacks share the same signature, func(attr, old, new), and this example just doesn't do anything with attr. Short answer for why it isn't used: no particular reason...

    You could easily rewrite it like so:

    def my_text_input_handler(attr, old, new):
        print("attr: " + attr)
        print("Previous label: " + old)
        print("Updated label: " + new)
    

    attr corresponds to "value" in text_input.on_change("value", my_text_input_handler).

    1. The "value" parameter passed to the text_input.on_change function is the name of the text_input attribute that you are watching. So, every time the "value" attribute changes of the text_input object, the callback function (my_text_input_handler) is invoked with with attribute name ("value") and the old and new values.

    Take a look at this HTML/Javascript example to better understand what it is doing: https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onchange2

    Here is an example that will help illustrate what the callback is doing. Save this code as "demo.py", run it via bokeh serve demo.py and check out how it works.

    ''' 
    Use the ``bokeh serve`` command to run the example by executing:
    
        bokeh serve demo.py
    
    at your command prompt. Then navigate to the URL
    
        http://localhost:5006/demo
    
    in your browser.
    
    '''
    
    from bokeh.io import curdoc
    from bokeh.models import TextInput
    
    def my_text_input_handler(attr, old, new):
        print("attr: " + attr)
        print("Previous label: " + old)
        print("Updated label: " + new)
    
    text_input = TextInput(value="default", title="Label:")
    text_input.on_change("value", my_text_input_handler)
    
    curdoc().add_root(text_input)
    
    
    1. Check your terminal/command line for the output, not your browser's javascript console.

    Your original code should indeed print:

    Previous label: default
    Updated label: test