Unhandled Rejection (Error): Model 'DrawTool' does not exist

I am trying to add the drawtool from the docs example: A new custom tool — Bokeh 2.4.2 Documentation

to my website. The code is as follows:

class DrawTool(Tool):# Tool
    __implementation__ = TypeScript(
        """
import {GestureTool, GestureToolView} from "models/tools/gestures/gesture_tool"
    import {ColumnDataSource} from "models/sources/column_data_source"
    import {PanEvent} from "core/ui_events"
    import * as p from "core/properties"

    export class DrawToolView extends GestureToolView {
    model: DrawTool

    //this is executed when the pan/drag event starts
    _pan_start(_ev: PanEvent): void {
        this.model.source.data = {x: [], y: []}
    }

    //this is executed on subsequent mouse/touch moves
    _pan(ev: PanEvent): void {
        const {frame} = this.plot_view

        const {sx, sy} = ev
        if (!frame.bbox.contains(sx, sy))
        return

        const x = frame.x_scale.invert(sx)
        const y = frame.y_scale.invert(sy)

        const {source} = this.model
        source.get_array("x").push(x)
        source.get_array("y").push(y)
        source.change.emit()
    }

    // this is executed then the pan/drag ends
    _pan_end(_ev: PanEvent): void {}
    }

    export namespace DrawTool {
    export type Attrs = p.AttrsOf<Props>

    export type Props = GestureTool.Props & {
        source: p.Property<ColumnDataSource>
    }
    }

    export interface DrawTool extends DrawTool.Attrs {}

    export class DrawTool extends GestureTool {
    properties: DrawTool.Props
    __view_type__: DrawToolView

    constructor(attrs?: Partial<DrawTool.Attrs>) {
        super(attrs)
    }

    tool_name = "Drag Span"
    icon = "bk-tool-icon-lasso-select"
    event_type = "pan" as "pan"
    default_order = 12

    static init_DrawTool(): void {
        this.prototype.default_view = DrawToolView

        this.define<DrawTool.Props>(({Ref}) => ({
        source: [ Ref(ColumnDataSource) ],
        }))
    }
    }
        """
    )
    source = Instance(ColumnDataSource)

    p = createfigure(...)
    drawsource = ColumnDataSource(data=dict(x=[], y=[]))
    d = DrawTool(source=drawsource)
    p.line('x', 'y', source=drawsource)
    p.add_tools(d)
   return json_item(p)

But I am getting this error on my client:

Unhandled Rejection (Error): Model 'DrawTool' does not exist. This could be due to a widget or a custom model not being registered before first usage.
u.get
https://cdn.bokeh.org/bokeh/release/bokeh-2.3.2.min.js:166:1004
Function._instantiate_object
https://cdn.bokeh.org/bokeh/release/bokeh-2.3.2.min.js:165:4805
Function._instantiate_references_json
https://cdn.bokeh.org/bokeh/release/bokeh-2.3.2.min.js:165:4993
Function.from_json
https://cdn.bokeh.org/bokeh/release/bokeh-2.3.2.min.js:165:8491
w
https://cdn.bokeh.org/bokeh/release/bokeh-2.3.2.min.js:163:398
t.embed_item
https://cdn.bokeh.org/bokeh/release/bokeh-2.3.2.min.js:163:1336

Somehow i need to register the tool it seems - but I do not understand how to do that.
I hope a kind soul could explain to me what I am missing here :slight_smile:

Thanks in advance

@bokehcoder you need to provide more information about how/where you are actually using the extensions. Is this in a notebook? In a bokeh server app? In standalone content? If so, how are you emebedding? (e.g. note that json_items does not yet support including extensions)

Hi @Bryan
Thanks for the response. So yeah, I am fetching the plot on my frontend (not a notebook or bokeh server, but a react frontend) as a json_item via a GET whereafter i am embedding the returned json via Bokeh.embed.embed_item.

So what you are telling me is that this is currently not possible?

Not currently with json_items. The components function can support extensions, and has some options to return raw data rather than script tags, so it should be usable in the sort of scenario you describe.

I have update the code to use components now but i am still getting the same error. The stacktrace is a bit different though:

Uncaught (in promise) Error: Model 'DrawTool' does not exist. This could be due to a widget or a custom model not being registered before first usage.
    at u.get (bokeh-2.3.2.min.js:166)
    at Function._instantiate_object (bokeh-2.3.2.min.js:165)
    at Function._instantiate_references_json (bokeh-2.3.2.min.js:165)
    at Function.from_json (bokeh-2.3.2.min.js:165)
    at w (bokeh-2.3.2.min.js:163)
    at Object.t.embed_items (bokeh-2.3.2.min.js:163)

Do you have any idea what else could be missing @Bryan ?

I can’t speculate without a complete Minimal Reproducible Example.

ok, it works with components - turns out i had some other javascript that was messing with the model registration