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:

Hey Emil, what is app_id referring to here? I am using the assets folder and created it in the Code Library; however, I could not find a way to reference it in the Dash Webapp

It is a string that is unique across all of the apps in you Dataiku project.

Thanks for the response @Emil. Do you know where can I get that string? Also, where did you define the assets folder? Is it on the Code Library section?

You define it yourself (see e.g. the example code block posted earlier in this thread).