Clarification on bokeh's callback

Viewed 558

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.

1 Answers

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
Related