plotly / dash

Data Apps & Dashboards for Python. No JavaScript Required.

Home Page:https://plotly.com/dash

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG] Dash 2.16.0

AnnMarieW opened this issue · comments

Here's another example of an app that worked in 2.15 but not in 2.16 Might be related to some already reported issues, but it looks slightly different.

Cannot read properties of undefined (reading 'DashIconify')

This error originated from the built-in JavaScript code that runs Dash apps. Click to see the full stack trace or open your browser's console.)
TypeError: Cannot read properties of undefined (reading 'DashIconify')

    at dagcomponentfuncs.DMC_Button (http://127.0.0.1:8050/assets/dashAgGridComponentFunctions.js?m=1709410368.1990933:384:60)

    at renderWithHooks (http://127.0.0.1:8050/_dash-component-suites/dash/deps/react-dom@16.v2_16_0m1709588564.14.0.js:14938:20)

    at mountIndeterminateComponent (http://127.0.0.1:8050/_dash-component-suites/dash/deps/react-dom@16.v2_16_0m1709588564.14.0.js:17617:15)

    at beginWork (http://127.0.0.1:8050/_dash-component-suites/dash/deps/react-dom@16.v2_16_0m1709588564.14.0.js:18731:18)

    at HTMLUnknownElement.callCallback (http://127.0.0.1:8050/_dash-component-suites/dash/deps/react-dom@16.v2_16_0m1709588564.14.0.js:182:16)

    at Object.invokeGuardedCallbackDev (http://127.0.0.1:8050/_dash-component-suites/dash/deps/react-dom@16.v2_16_0m1709588564.14.0.js:231:18)

    at invokeGuardedCallback (http://127.0.0.1:8050/_dash-component-suites/dash/deps/react-dom@16.v2_16_0m1709588564.14.0.js:286:33)

    at beginWork$1 (http://127.0.0.1:8050/_dash-component-suites/dash/deps/react-dom@16.v2_16_0m1709588564.14.0.js:23338:9)

    at performUnitOfWork (http://127.0.0.1:8050/_dash-component-suites/dash/deps/react-dom@16.v2_16_0m1709588564.14.0.js:22292:14)

    at workLoopSync (http://127.0.0.1:8050/_dash-component-suites/dash/deps/react-dom@16.v2_16_0m1709588564.14.0.js:22265:24)
import json
import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output
import pandas as pd
import dash_mantine_components as dmc
import dash_iconify


data = {
    "ticker": ["AAPL", "MSFT", "AMZN", "GOOGL"],
    "company": ["Apple", "Microsoft", "Amazon", "Alphabet"],
    "price": [154.99, 268.65, 100.47, 96.75],
    "buy": ["Buy" for _ in range(4)],
    "sell": ["Sell" for _ in range(4)],
    "watch": ["Watch" for _ in range(4)],
}
df = pd.DataFrame(data)

columnDefs = [
    {
        "headerName": "Stock Ticker",
        "field": "ticker",
    },
    {"headerName": "Company", "field": "company", "filter": True},
    {
        "headerName": "Last Close Price",
        "type": "rightAligned",
        "field": "price",
        "valueFormatter": {"function": """d3.format("($,.2f")(params.value)"""},
    },
    {
        "field": "buy",
        "cellRenderer": "DMC_Button",
        "cellRendererParams": {
            "variant": "outline",
            "leftIcon": "ic:baseline-shopping-cart",
            "color": "green",
            "radius": "xl"
        },
    },
    {
        "field": "sell",
        "cellRenderer": "DMC_Button",
        "cellRendererParams": {
            "variant": "outline",
            "leftIcon": "ic:baseline-shopping-cart",
            "color": "red",
            "radius": "xl"
        },
    },
{
        "field": "watch",
        "cellRenderer": "DMC_Button",
        "cellRendererParams": {
            "rightIcon": "ph:eye",
        },
    },
]


defaultColDef = {
    "resizable": True,
    "sortable": True,
    "editable": False,
}


grid = dag.AgGrid(
    id="custom-component-dmc-btn-grid",
    columnDefs=columnDefs,
    rowData=df.to_dict("records"),
    columnSize="autoSize",
    defaultColDef=defaultColDef,
)


app = Dash(__name__)

app.layout = html.Div(
    [
        dcc.Markdown("Example of cellRenderer with dash-mantine-components Button  and DashIconify icons"),
        grid,
        html.Div(id="custom-component-dmc-btn-value-changed"),
    ],
    style={"margin": 20},
)


@app.callback(
    Output("custom-component-dmc-btn-value-changed", "children"),
    Input("custom-component-dmc-btn-grid", "cellRendererData"),
)
def showChange(n):
    return json.dumps(n)


if __name__ == "__main__":
    app.run_server(debug=True)


"""
Put the following in the dashAgGridComponentFunctions.js file in the assets folder

---------------

var dagcomponentfuncs = window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {};

dagcomponentfuncs.DMC_Button = function (props) {
    const {setData, data} = props;

    function onClick() {
        setData();
    }
    let leftIcon, rightIcon;
    if (props.leftIcon) {
        leftIcon = React.createElement(window.dash_iconify.DashIconify, {
            icon: props.leftIcon,
        });
    }
    if (props.rightIcon) {
        rightIcon = React.createElement(window.dash_iconify.DashIconify, {
            icon: props.rightIcon,
        });
    }
    return React.createElement(
        window.dash_mantine_components.Button,
        {
            onClick,
            variant: props.variant,
            color: props.color,
            leftIcon,
            rightIcon,
            radius: props.radius,
            style: {
                margin: props.margin,
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
            },
        },
        props.value
    );
};



"""

The example uses a custom renderer in ag grid, it bypass the dynamic loading of the renderer. dash_iconify and dmc are not in the actual layout and thus not loaded, workaround for this is to use preloaded_libraries=['dash_iconify', 'dash_mantine_components'] that way they are loaded on the index.

Good to know - thanks! I'll add this to the docs.

Worked for me I only changed this line in the example:

app = Dash(__name__, preloaded_libraries=['dash_iconify', 'dash_mantine_components'])

image

Yes - it works for me too once I fixed my typo. Thanks for following up 🙂