Skip to content

Local JS-dependency not available on mount for custom component (d3.js) #4243

Closed
@ursa-minor-13

Description

@ursa-minor-13

Description

I'm working with d3.js-based visualizations ([email protected] -- https://cdn.jsdelivr.net/npm/d3@7) inside a custom component ([email protected]).
When refactoring my component to the new unified 3rd-party dependency declaration (#2991), the locally served library gets imported, but there seems to be an issue during the import:

When the component is initialized, an error is thrown: d3.select is not a function (for code example, see below).
Running the same d3.js-based command afterwards from the console produces the correct result (as indicated by the image below).

I'm currently unsure whether this is a nicegui- or js-import-related problem.
However, based on the fact that the module is available later, I'd assume that there is some timing problem related to nicegui.

Image


Minimal example (using dependencies -- throws error)

Python-component:

from nicegui import ui, app
from nicegui.element import Element as NiceGuiBaseElement

class VizContainer(NiceGuiBaseElement, component='VizContainer.js', dependencies=['./d3.js']):
    
    def __init__(self, tag = None, *, _client = None):
        super().__init__(tag, _client=_client)
        self._props = {'svg_width': 500,'svg_height': 500,}

myViz = VizContainer()

app.native.start_args['debug'] = True
ui.run(native=True)

JS-component:

import * as d3 from 'd3';

export default {
    name: 'VisualComponent',
    template: `
      <div id="svg-body">
        <svg id="svg" :width="$props.svg_width" :height="$props.svg_height"></svg>
      </div>
      `,
    mounted() {
        this.initSVG()
    },
    props: [
        'svg_width',
        'svg_height'
    ],
    methods: {
        initSVG() {
            d3.select('#svg').append('circle').attr('r', '200px').style('fill','red')
        }
    },
}

Minimal example (using deprecated libraries -- runs as intended)

Python-component:

from nicegui import ui, app
from nicegui.element import Element as NiceGuiBaseElement

class VizContainer(NiceGuiBaseElement, component='VizContainer.js', libraries=['./d3.js']):
    
    def __init__(self, tag = None, *, _client = None):
        super().__init__(tag, _client=_client)
        self._props = {'svg_width': 500,'svg_height': 500,}

myViz = VizContainer()

app.native.start_args['debug'] = True
ui.run(native=True)

JS-component:

export default {
    name: 'VisualComponent',
    template: `
      <div id="svg-body">
        <svg id="svg" :width="$props.svg_width" :height="$props.svg_height"></svg>
      </div>
      `,
    mounted() {
        this.initSVG()
    },
    props: [
        'svg_width',
        'svg_height'
    ],
    methods: {
        initSVG() {
            d3.select('#svg').append('circle').attr('r', '200px').style('fill','red')
        }
    },
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions