Giter Site home page Giter Site logo

Comments (17)

chriddyp avatar chriddyp commented on August 18, 2024 6

So, I think that ideally we would allow circular relationships like this:

# clicking on radio item updates the URL
@app.callback(Output('location', 'pathname'), [Input('radio', 'value')])
def update_pathname(value):
     return '/{}'.format(value)

# landing on a page directly updates the radio item navigator
@app.callback(Output('radio', 'value'), [Input('location', 'pathname')])
def sync_pathname(value):
     return value.strip('/')

With support for previous state (plotly/dash-renderer#25), we would be able to eventually do something like:

@app.callback(
    Output('store', 'children'),
    [Input('radio', 'value'), Input('location', 'pathname')],
    [PrevState('radio', 'value'), PrevState('location', 'pathname')])
def update_current_location(radio, path, prevRadio, prevPath):
    if radio != prevRadio:
         return '/{}'.format(radio)
    elif path != prevPath:
         return path

@app.callback(Output('radio', 'value'), [Input('store', 'children')])
def update_radio(path):
    return path

@app.callback(Output('location', 'pathname'), [Input('store', 'children')])
def update_path(path):
    return path

Which might make the code a little bit cleaner (easier to add more items that depend on the current path). However, we still run into the issue of having circular dependencies.

from dash-core-components.

chriddyp avatar chriddyp commented on August 18, 2024 4

Thanks for opening @tahouse ! Yes, this would be great and you're correct that this isn't supported right now.

Dash doesn't support "synced" components (there is a better name for this but I can't recall what it is, maybe "two way bindings" would be a better way to describe it.)

In the case for URLs, we need the following flows:
URL -> Updates Component
Component Changes -> Updates URL

If you think about this in reactive terms like as in an Excel spreadsheet, this would cause an infinite loop - changing the URL updates the component which then updates the URL which then updates the component, etc.

What Dash should do is update the components and then stop when it detects a loop like this. Or, allow the user to configure the number of loops that it should execute before stopping (like a discrete dynamical system that eventually converges).

Then, you could write these relationships that depend on each other.


This actually comes up a lot. If we want to enable users to write and share complex models with "what if" scenarios where every parameter is configurable, then we'll need to support this. For example, pulling from Bret Victor's Explorable Explanations (http://worrydream.com/ExplorableExplanations/):

Suppose that an extra $17 was charged to 85% of vehicle registrations. Park admission would be free for those who paid the charge.
This would collect an extra $338 million for a total state park budget of $738 million.

In that case, every word that is in the code syntax would be variable: you could modify any of those parameters and see the rest of the parameters update. This would require a lot of coding - for each component (you'd need to solve for the inverse relationship of that parameter and your UI would have to fix some variables in those inverse relationships), but it might be pretty cool.


Long story short, I'd like to support this use case. In the meantime, I'm not aware of any other workarounds.

from dash-core-components.

nkrumm avatar nkrumm commented on August 18, 2024 3

I would love this feature as well. I've tried playing with the internals dcc.Location component, but always ended up with various infinite loops or dead-ends.

Recently just saw the addition of the state input callback, and thought that this might be a solution to the problem here... but before embarking on attempting that I thought I would circle back here and see if any progress or changes were planned to the URL/location component.

from dash-core-components.

glennlawyer avatar glennlawyer commented on August 18, 2024 3

Upvoting this. My particular use case is selecting the URL from a dropdown, because we have more pages than fits in a menu bar. I was able to create the infinite loop pretty easily by having the dropdown update the url, and the url update the page (which re-loaded the header with the dropdown)...

from dash-core-components.

syamajala avatar syamajala commented on August 18, 2024 1

Any updates on this issue?

In the latest release, I tried to update a location pathname as the output of callback and ended up stuck in an infinite loop.

EDIT:
I posted an example of what I'm trying to do here:
https://community.plot.ly/t/multiple-pages-and-html-forms/10411

from dash-core-components.

ldorigo avatar ldorigo commented on August 18, 2024 1

Hi,

Is there still no way to do this? I have tried updating the location with:

@app.callback(
          Output("location", "pathname")
          Input(f"test", "value")
)
def update_location(val):
    return "foo"

And it returns correctly but doesn't actually change the in-browser URL.

from dash-core-components.

ned2 avatar ned2 commented on August 18, 2024 1

Hey @ldorigo, this repo is no longer used; it's been migrated into https://github.com/plotly/dash

from dash-core-components.

Spin45 avatar Spin45 commented on August 18, 2024

Just adding another vote for this feature.

I believe this is generally referred to as "deep linking" (at least that's what Adobe Flex called it) and when applied to a web application is specifically referring to RESTful invocation of an application's state via its URL with the updating of the URL as the application is used, so as to continue to allow the back button in browsers to work (core usability) and states of the web application to be shared via URL as mentioned above.

We are hoping to build a general purpose Plotly app for our Earth science data visualization applications that can be launched from our other web applications via RESTful URLS (I believe this already works). However, we want to make our Plotly app powerful and configurable and not being able to preserve the Plotly app's state after many operations, via an updated URL is an issue.

from dash-core-components.

chriddyp avatar chriddyp commented on August 18, 2024

I believe this is generally referred to as "deep linking" (at least that's what Adobe Flex called it) and when applied to a web application is specifically referring to RESTful invocation of an application's state via its URL with the updating of the URL as the application is used, so as to continue to allow the back button in browsers to work (core usability) and states of the web application to be shared via URL as mentioned above.

I think that this is actually a separate issue than circular states, in that it's more of a built-in "save state in url" plotly/dash#188

from dash-core-components.

bpostlethwaite avatar bpostlethwaite commented on August 18, 2024

Hi @syamajala thanks for posting. Better Location handling is on the short-term roadmap but I can't guarantee any particular dates right now. We'll update this thread once we have more info

from dash-core-components.

Zylatis avatar Zylatis commented on August 18, 2024

Upvoting this as I would like to have a multi-user app where the URL is the user information I need to feed into the callbacks to display the correct things.

from dash-core-components.

NikTheGeek1 avatar NikTheGeek1 commented on August 18, 2024

Upvoting here as well

from dash-core-components.

simone-pignotti avatar simone-pignotti commented on August 18, 2024

Upvoting too! Thanks @chriddyp for the thorough explanation.

from dash-core-components.

usser123 avatar usser123 commented on August 18, 2024

Upvoting too.

I have tried to redirect to a specific page after successful login. I encountered problems with both the ways that I tried:

  1. By using the callback where url is both the input and the output, I received a dash exception.
  2. By using dcc.Location in the callback function, the url does not actually get updated in the browser. Same problem as described in the very first post in this thread.

from dash-core-components.

rsandler00 avatar rsandler00 commented on August 18, 2024

Any updates on this? Would also love to have!

from dash-core-components.

jimkrooskos avatar jimkrooskos commented on August 18, 2024

Looking for a solution for this as well!

from dash-core-components.

codepatel avatar codepatel commented on August 18, 2024

I came across this issue, when I was searching for the same feature in Dash API.
I agree with @chriddyp on the Circular dependency between the URL.pathname and Layout Elements that are data-triggered and data-driven. I will share a workaround for the very common use-cases in sharing and collaborating Dashboards (also posted on this Medium story: https://medium.com/@hardiksp/how-to-solve-the-dependency-when-sharing-and-collaborating-on-useful-dashboard-apps-with-the-dash-d136a21023e0)

  1. You want the Dashboard author to share with Users the deployed app layout and data analysis presentation (with a custom URL served to get to the "State" of Dashboard) - This is done by parsing the URL and then using the Redis key/value pair as an in-memory data structure store. Key will be a session-based UUID and can optionally also have URL pieces to search for inspection or data-crunching.
  2. Now, users with this "State" of Dashboard will want to make more modifications like what-if scenarios on the inputs that will trigger output callbacks. To save this "new" what-if state of the Dashboard app, there is a user button, that will take the dcc.Store component's saved output callback values, to save to a Redis data store.
  3. This user-action will generate a new URL shown with a dcc.Link component that can be used to rinse and repeat the cycle.

image

Gist for this UI callbacks

Here are the links to:

  1. The deployed app: https://dcf-valuation-damodaran.herokuapp.com/apps/dcf/AAPL
  2. Source code repo: https://github.com/codepatel/dcf#how-to-setup-this-app-locally

Note, I didn't save all the output callback values in the data cache store in Redis, only the final output states of the data that was important and not output figures or tables. This can be easily done for figures' state by also saving the dict for fig.data and fig.layout in a dcc.Store component.
Ideally, if dcc has a future way to make this process more abstracted with all output callbacks in the app layout, rather than the user having to pick and choose output callback to save to a cache, then any Dashboard state can be restored given a unique, custom URL in sharing and collaboration.
(I used Redis to cache data as I was new to learning it, but a filesystem cache can also be used with the dict key/pair management).

Please let me know if any feedback on the above approach for suggestions.

from dash-core-components.

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.