Announcing Dash Bio 1.0.0 🎉 : a one-stop-shop for bioinformatics and drug development visualizations.

Dash on Dataiku, dashExtensions.default.function0, assign error

Hi,

I developed a dash WebApp locally on my computer and it works beautifuly. I got a map (dash-leaflet) in the App which displays different icons. These icons are sourced from url using the assign function from dash_extensions.

icon=assign("""function(feature, latlng){
const flag = L.icon({iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png', iconSize: [15, 20]});
return L.marker(latlng, {icon: flag});
}""")

and then

marker=dl.GeoJSON(data=data,id='marker',options=dict(pointToLayer=icon))

When deploying the app on Dataiku, I am struggling to access the png resource and I got the following message when inspecting the Webpage.

From my understanding dashExtensions.default.function0 is the object stored in icon variable from the assign function.

I got 2 questions from here:

  1. Is the current issue on Dataiku server side?
  2. Is there any other way to custom icon for GeoJSON objects? (by loading images directly in the App for instance?)

Regards

Most likely, it has to do with the way Dataiku hosts your app. What version of Dataiku are you using?

Hi Emil,

I am using Dataiku DSS9, but I do not have hands on server side. I guess I have to get in touch with the admin team.

Thanks for the insight, and thanks for the awesome work.

Thanks. In DSS 9 it can be a bit challenging to get assets to work, but it can be done. Here is a small example that should work out of the box,

# Setup per-app assets folder.
import os
from dash_extensions.dataiku import bind_assets_folder
app_id = "my_app"
os.environ["ASSETS_FOLDER"] = f"assets/{app_id}"
assets_folder = os.path.join(os.getcwd(), "assets")
os.makedirs(assets_folder, exist_ok=True)

# region Normal Dash app

import dash_html_components as html
import dash_leaflet as dl
import dash_leaflet.express as dlx
from dash_extensions.enrich import DashProxy
from dash_extensions.javascript import assign
# A few countries.
countries = [dict(name="Denmark", iso2="dk", lat=56.26392, lon=9.501785),
             dict(name="Sweden", iso2="se", lat=59.334591, lon=18.063240),
             dict(name="Norway", iso2="no", lat=59.911491, lon=9.501785)]
# Generate geojson with a marker for each country and name as tooltip.
geojson = dlx.dicts_to_geojson([{**c, **dict(tooltip=c['name'])} for c in countries])
# Create javascript function that draws a marker with a custom icon, in this case a flag hosted by flagcdn.
draw_flag = assign("""function(feature, latlng){
const flag = L.icon({iconUrl: `https://flagcdn.com/64x48/${feature.properties.iso2}.png`, iconSize: [64, 48]});
return L.marker(latlng, {icon: flag});
}""")
# Create example app.
my_app = DashProxy()
my_app.layout = html.Div([
    dl.Map(children=[
        dl.TileLayer(), dl.GeoJSON(data=geojson, options=dict(pointToLayer=draw_flag), zoomToBounds=True)
    ], style={'width': '100%', 'height': '50vh', 'margin': "auto", "display": "block"}, id="map"),
])

# endregion

# Inject state into the app object from dataiku.
bind_assets_folder(app, app_id , assets_folder)
my_app.hijack(app)

Hi Emil, I found similar error when I try to implement Dash in a Flask app.
This time the problem comes when using:

    point_to_layer = assign("""function(feature, latlng, context){
        const {min, max, colorscale, circleOptions, colorProp} = context.props.hideout;
        const csc = chroma.scale(colorscale).domain([min, max]);  // chroma lib to construct colorscale
        circleOptions.fillColor = csc(feature.properties[colorProp]);  // set color based on color prop.
        return L.circleMarker(latlng, circleOptions);  // sender a simple circle marker.
    }""")

The error seems to be in the assets/dashExtensions_default.js generated.
Is there any way to avoid it?

Thanks for your time!

What version of DSS are you on?

Hi Emil,

I am not using Dataiku DSS. I am embedding Dash app in a Flask app.
The version that I am using currently are the latest for each library:

  • dash==2.0.0
  • dash-leaflet==0.1.23
  • flask==1.1.2

I am a newbie with Flask and Dash, so please correct me if I was mistaken :slight_smile:

Cheers

Ah, okay. Then it is probably just because you haven’t setup the assets folder correctly, I.e. the way Dash normally does it :slight_smile:

Thanks Emil!
Yes, adding the parameter assets_folder='my_path_to_assets' solved the issue.

Unfortunately, a new one appeared:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'map')
It seems to me, to be related to Dash_leaflet library and the asynchronous feature of React:

For some reason this error only appears when I embed Dash in a Flask app. :confused:

That could be a dash-leaflet bug, but I would need to see some example code yielding the error to be sure. Can you make a MWE?

Hi Emil, I found the reason!

I was trying to reproduce a minimum working example of the scatter plot with Dash_leaflet library:
https://dash-leaflet.herokuapp.com/#scatter_plot

My mistake was that I didn’t indicate the format of the geoJson object at:
geojson = dl.GeoJSON(data=geobuf,id="geojson", format="geobuf", options=dict(pointToLayer=point_to_layer))

Thanks for your time :slight_smile:
Jose.

Good to hear that you got it working :slight_smile: