emilhe / dash-leaflet

MIT License
213 stars 37 forks source link

"Interactivity via the hideout prop" example breaks when running app in debug-mode #155

Closed baender closed 1 year ago

baender commented 2 years ago

When playing around with the interactive GeoJSON example, I stumbled across this error when using app.run_server(debug=True)

Invalid argument `hideout` passed into GeoJSON with ID "geojson".
Expected one of type [string, object].
Value provided: 
[
  "Aalborg",
  "Aarhus",
  "Copenhagen"
]

I posted the code here as well but the only change from the example on the website is the debug argument, everything else is identical. Setting the argument to False produces the working result.

import dash_leaflet as dl
import dash_leaflet.express as dlx
from dash import Dash, html, dcc, Output, Input
from dash_extensions.javascript import assign

# A few cities in Denmark.
cities = [dict(name="Aalborg", lat=57.0268172, lon=9.837735),
          dict(name="Aarhus", lat=56.1780842, lon=10.1119354),
          dict(name="Copenhagen", lat=55.6712474, lon=12.5237848)]
# Create drop down options.
dd_options = [dict(value=c["name"], label=c["name"]) for c in cities]
dd_defaults = [o["value"] for o in dd_options]
# Generate geojson with a marker for each city and name as tooltip.
geojson = dlx.dicts_to_geojson([{**c, **dict(tooltip=c['name'])} for c in cities])
# Create javascript function that filters on feature name.
geojson_filter = assign("function(feature, context){return context.props.hideout.includes(feature.properties.name);}")
# Create example app.
app = Dash()
app.layout = html.Div([
    dl.Map(children=[
        dl.TileLayer(),
        dl.GeoJSON(data=geojson, options=dict(filter=geojson_filter), hideout=dd_defaults, id="geojson", zoomToBounds=True)
    ], style={'width': '100%', 'height': '50vh', 'margin': "auto", "display": "block"}, id="map"),
    dcc.Dropdown(id="dd", value=dd_defaults, options=dd_options, clearable=False, multi=True)
])
# Link drop down to geojson hideout prop (could be done with a normal callback, but clientside is more performant).
app.clientside_callback("function(x){return x;}", Output("geojson", "hideout"), Input("dd", "value"))

if __name__ == '__main__':
    app.run_server(debug=True)
emilhe commented 1 year ago

Ah, yes. That's a bug, it's the type validator that's too strict. However, it won't affect your app in any way (other than raising an error when running in debug mode)

asmusvm commented 1 year ago

I had the same issue in the debug mode with the hideout argument and the type validator. The problem also occurs with the subdomains argument, when handing a list of subdomains to the TileLayer.

Invalid argument `subdomains` passed into TileLayer.
Expected `string`.
Was supplied type `array`.
Value provided: []

grafik

Subdomains code: dl.TileLayer(url= "...", subdomains=[..., ...])

The Dash debug mode is quite convenient and I would rather not give it up. Maybe there is a way to make the validator less strict or add the allowed types to the validator ... Is it the javascript side validator of the leaflet package?

emilhe commented 1 year ago

Should be fixed in 1.0.2.