Code Monkey home page Code Monkey logo

Comments (23)

emilhe avatar emilhe commented on June 14, 2024 1

Could you try with 3.9? And maybe without anaconda (I doubt it's related, but I don't use it)? (just the small example, so that we can locate the origin of the error)? Altså, I am testing with Chrome browser.

from dash-extensions.

luggie avatar luggie commented on June 14, 2024 1

yep, my minimal example for me works on python 3.9.1 (on a fresh anaconda env with just the needed packages). I'll confirm again, if this also works with my full dash app

from dash-extensions.

emilhe avatar emilhe commented on June 14, 2024

What version are you on? Could you share the line where you construct the transform?

from dash-extensions.

jrkkfst avatar jrkkfst commented on June 14, 2024

I'm on 0.0.53.

app = DashProxy(
    transforms=[
        MultiplexerTransform(proxy_location=None),
        NoOutputTransform(),
    ],
)

It's for saving data in a dcc.Store and then retrieving it. And i Have multiple callbacks accessing the State of the Store object and then Also as Output.

I tried different thing with dcc.Store or just using a hidden html

It's a little complex because I have a class which creates the html objects and callbacks on launch, and then I create multiple objects of that class.

I am adding the callback without the decorator directly by calling app.callback, it hasn't worked with the decorator function.

Some code snippets:

This is the html object where I initialise the children as None. It is here I would expect if I didn't initialize it may cause error, but I set it.

html.Div(None, id=f"{self.id}_storage", style={"display": "none"})

How I create the callbacks

callback = self.make_callback(
   # function that returns the appropriate callback function
)
app.callback(
    Output(f"{self.id}_storage", "children"),
    [
        State(f"{self.id}_storage", "children"),
    ],
    prevent_initial_call=True,
)(callback)

from dash-extensions.

jv1522 avatar jv1522 commented on June 14, 2024

I also faced this error. Can we have multiple dashh_extensions.enrich.Outputs in callbacks?

from dash-extensions.

emilhe avatar emilhe commented on June 14, 2024

@jv1522 yes that should be possible

from dash-extensions.

emilhe avatar emilhe commented on June 14, 2024

The error seems to indicate that the layout is not defined at the time where the multiplexer is called. I am not really sure how this can happen, but if you can share a reproducible example, I can try to address the problem. Until then, a possible workaround could be to "manually" place the proxy components in the layout, i.e.

proxy_container = html.Div()
app = DashProxy(transforms=[MultiplexerTransform(proxy_location=proxy_container)])

and then making sure that the proxy_container is added to the layout,

app.layout = html.Div([..., proxy_container])

from dash-extensions.

jv1522 avatar jv1522 commented on June 14, 2024

Can we have dash extension's output and the plain dash's Output in the same callback, here is the code example
In the below the duplicate_id is being used in another callback with dash extensions' Output

from dash.dependencies import Output
from dash_extensions.enrich import Output as Extended_Output

@app.callback(
    Output("unique_id1", "children"),
    Output("unique_id2", "data"),
    Extended_Output("duplicate_id", "children"),
    Input("id1", "value")
)
def do_something():
    pass

from dash-extensions.

emilhe avatar emilhe commented on June 14, 2024

I am not sure I understand why you don't just use the Output from dash_extensions.enrich for all the outputs? That would seem simpler

from dash-extensions.

jrkkfst avatar jrkkfst commented on June 14, 2024

The error seems to indicate that the layout is not defined at the time where the multiplexer is called. I am not really sure how this can happen, but if you can share a reproducible example, I can try to address the problem. Until then, a possible workaround could be to "manually" place the proxy components in the layout, i.e.

proxy_container = html.Div()
app = DashProxy(transforms=[MultiplexerTransform(proxy_location=proxy_container)])

and then making sure that the proxy_container is added to the layout,

app.layout = html.Div([..., proxy_container])

I still can't get it to work. I'm sorry I cannot easily provide a minimal working example.

It seems the proxy_container is not correctly populated even when I follow your example. First I initialize the app, then using my class create a number of objects with both html components and their callbacks, then I add those html components to my app.layout. It seems somehow the proxy_container isn't populated correctly.

Do I need to use the: from dash_extensions.enrich import Output ?

I think one key is that I define the proxy_container in the start, and then I create my objects using the classes I have, which makes the html components and callsback. At some point here the proxy_container should modified, and that modified proxy_container has to be fed into the final app.layout, as you suggest. However, because I'm using multiple python files, it is not obvious for me how to do the import of it back and forth to ensure, I then use the final version of the proxy_container.

from dash-extensions.

jrkkfst avatar jrkkfst commented on June 14, 2024

A key problem could be that I use a class to generate multiple different objects and then I assume that each of the instances of these objects may have added snippets to the proxy_container, and I'm not "saving" all those changes to the proxy_container and adding them "on top of" one another.

from dash-extensions.

luggie avatar luggie commented on June 14, 2024

any news on this? I have the same behavior. Also for me it is very hard if not impossible to provide a minimal working example. I'm also adding the app.layout inside a class in another file as my DashProxy declaration. My callbacks are also spread across a lot of python files. unfortunately the error traceback doesn't provide help

TypeError: Cannot read properties of undefined (reading 'value')

at handleClientside (webpack://dash_renderer/./src/actions/callbacks.ts?:234:54)

at _callee$ (webpack://dash_renderer/./src/actions/callbacks.ts?:488:25)

at c (http://127.0.0.1:8050/_dash-component-suites/dash/dcc/async-slider.js:1:109231)

at Generator._invoke (http://127.0.0.1:8050/_dash-component-suites/dash/dcc/async-slider.js:1:109019)

at Generator.next (http://127.0.0.1:8050/_dash-component-suites/dash/dcc/async-slider.js:1:109656)

at asyncGeneratorStep (webpack://dash_renderer/./src/actions/callbacks.ts?:37:103)

at _next (webpack://dash_renderer/./src/actions/callbacks.ts?:39:194)

at eval (webpack://dash_renderer/./src/actions/callbacks.ts?:39:364)

at new Promise (<anonymous>)

at eval (webpack://dash_renderer/./src/actions/callbacks.ts?:39:97)

from dash-extensions.

emilhe avatar emilhe commented on June 14, 2024

The structure in terms of files shouldn't matter. But if you do some kind of dynamic modification of the app layout post load, it might. I don't see anything in the error message that seems to relate to the MultiplexerTransform, so I don't really have anything to go on in terms of debugging the issue.

If you can post a minimal example demonstrating the error, I can take a look.

from dash-extensions.

jrkkfst avatar jrkkfst commented on June 14, 2024

The problem still remains for me and I have to solve it in the future. It is still complex to make a simple minimal working example, but it seems that one of us may have to create one soon.

from dash-extensions.

luggie avatar luggie commented on June 14, 2024

Yes same here, I cannot get my dash up running with creating those Store-trigger chains manually myself. When creating generic callbacks like in a loop, it scales quite dramatically :D
I'll start to think about how to create a minimal example and post it soon

from dash-extensions.

luggie avatar luggie commented on June 14, 2024

For my, the problem is component specific. Does the following example also through an error for you?
It does for me, if the target component is a dcc.Dropdown, targeting its value.

from dash_extensions.enrich import MultiplexerTransform, DashProxy
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
from dash import html
from dash import dcc

app = DashProxy(__name__,
                transforms=[MultiplexerTransform()])


app.layout = \
    html.Div([
        dcc.Dropdown('dropdown-target', options=[{'label': 'option 1',  'value': 'option 1'},
                                                 {'label': 'option 2',  'value': 'option 2'}]),
        dbc.Button('Fire callback 1', id='btn-fire-callback-1'),
        dbc.Button('Fire callback 2', id='btn-fire-callback-2')
    ])


@app.callback(Output('dropdown-target', 'value'),
              Input('btn-fire-callback-1', 'n_clicks'), prevent_initial_call=True)
def _fire_callback_1(n):
    if n:
        return 'option 1'


@app.callback(Output('dropdown-target', 'value'),
              Input('btn-fire-callback-2', 'n_clicks'), prevent_initial_call=True)
def _fire_callback_1(n):
    if n:
        return 'option 2'


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

using:
dash 2.0.0
das-extensions 0.0.65
dash-bootstrap-components 1.0.1

from dash-extensions.

emilhe avatar emilhe commented on June 14, 2024

No, the example works for me. I just tried creating a new venv from scratch installing only the packages you listed. For reference, I am OSX using Python 3.9.1

from dash-extensions.

luggie avatar luggie commented on June 14, 2024

I use python 3.7.8 on Ubuntu 20.04. and anaconda 4.9.2

from dash-extensions.

emilhe avatar emilhe commented on June 14, 2024

Great. Let me know how it goes. If it works out, I'll add a note in the docs that Python 3.9 is recommended.

from dash-extensions.

luggie avatar luggie commented on June 14, 2024

Now it 'sort of works'. However, it feels very unstable. Here's why:
Before I heard about your MultiplexerTransform, I used to solve multiple outputs for components just like you did it in your extension: with chains of triggers 'funneling' many callbacks to one output. All manually. Now, whenever I 'free' one of those trigger funnels and 'release' two or more callbacks to output to the same component, I end up with the same error, I posted earlier. I can resolve it when I stop the dash app, clean my browser's cache and restart the app again. Hence dash loses its ability to hot-reload after changes which is quite annoying and doesn't feel save to be honest. Is this behavior expected or something that is easy to explain?

from dash-extensions.

emilhe avatar emilhe commented on June 14, 2024

It don't see why it should be be necessary to clear any cache. But if you do any modifications that change the component structure of the app, you might need to do a full refresh (e.g. app restart + browser reload, i.e. F5 or so) of the app to ensure that the auto generated multiplexing elements are created properly. I haven't worked much with hot reload, so I am not sure how well it integrates.

from dash-extensions.

emilhe avatar emilhe commented on June 14, 2024

In terms of "feeling safe", I would generally think that using a standardised implementation (like the one here) would be less error prone (and easier to maintain) as compared to manually implementing the logic each time. I am not saying it's error free, but I (and others) have used it across a number of apps without issues.

from dash-extensions.

luggie avatar luggie commented on June 14, 2024

It don't see why it should be be necessary to clear any cache. But if you do any modifications that change the component structure of the app, you might need to do a full refresh (e.g. app restart + browser reload, i.e. F5 or so) of the app to ensure that the auto generated multiplexing elements are created properly. I haven't worked much with hot reload, so I am not sure how well it integrates.

Yes the hot reloading does not integrate fully. The only difference between the behavior of Dash and DashProxy is the following:
Like I stated before, my app has loads of self made trigger chains that I now 'free' one-by-one using your extension. Every time I do so, I need to restart the page (even if app.run_server(debug=True) is set) to get the changes applied. Otherwise I get the error message, posted earlier. The hot reloading itself works. When I change anything that does not regard the functionality of MultiplexerTransform, changes in the layout or with callbacks are accepted right away. Maybe this helps if you are keen to trace this down. I'd be happy to help you with that, if you can think of any more information that you might need.

In terms of "feeling safe", I would generally think that using a standardised implementation (like the one here) would be less error prone (and easier to maintain) as compared to manually implementing the logic each time. I am not saying it's error free, but I (and others) have used it across a number of apps without issues.

99% agree. The only thing that is annoying, is that one does not get any useful information from error messages that simply say that "something went wrong in the JS backend". That being said: Thanks heaps for your effort in creating this extension and the instant support!

from dash-extensions.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.