-
-
Notifications
You must be signed in to change notification settings - Fork 30
Refactor DashR callbacks for increased parity with Dash for Python API #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
R/dash.R
Outdated
output=callback_signature$output, | ||
inputs=callback_signature$inputs, | ||
state=callback_signature$state, | ||
key=paste(callback_signature$output$id, callback_signature$output$property, sep='.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is key
a special keyword in R's lists? I'm assuming so, since I don't see this referenced anywhere else in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was present in the original code, but I can remove it. The key is also referenced here:
Line 55 in b05eaed
key = paste0(id, ".", property) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These key=
lines are still present 🔪
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 7e51f91
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 313dff1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Just a few small comments & questions
Thanks for taking the time to review. I'll make these initial edits and await Nadia and Alex's suggestions. |
Corrected basic example to function with current version of DashR interface.
Updated second example to work with updated DashR interface.
@alexcjohnson @chriddyp @TahiriNadia I've updated the examples in |
Added a note explaining `showcase=TRUE`.
Modified README.md to simplify arguments, remove id and property declarations.
Simplified arguments to first example.
Modify apps to use state, instead of specifying with input/type as before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one small item got left behind #51 (comment) but otherwise this is ready to go! 💃
R/dash.R
Outdated
@@ -328,6 +301,7 @@ Dash <- R6::R6Class( | |||
}, | |||
layout_set = function(...) { | |||
private$layout <- if (is.function(..1)) ..1 else list(...) | |||
lay <- private$layout_render() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line confuses me a bit, although it might just be my misunderstanding of R. Where is lay
being used?
- Is this setting it to the class?
- Does this also implicitly return
lay
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, why are we calling layout_render
here? Could we leave a comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, if you don't assign layout_render()
to an object, it returns the layout, which will display in the console.
There are a couple ways I could handle this -- I can wrap the return in invisible
, so that it silently returns the layout, which can be assigned to a new object. Or, I can add a silent
option which is TRUE
by default and let the app developer decide.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, why are we calling
layout_render
here? Could we leave a comment?
I mentioned this last week, but I think it got lost in the shuffle. If we don't render the layout when it's set, I don't believe it will get rendered until a GET
request occurs and is handled by routr
unless layout_get(render=TRUE)
is called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it returns the layout, which will display in the console.
Because if you didn't return the object but still needed to call private$layout_render()
, the code would look like:
layout_set = function(...) {
private$layout <- if (is.function(..1)) ..1 else list(...)
private$layout_render()
}
which would actually return private$layout_render()
(since it's the last line of the function).
But if we didn't need to call private$layout_render()
, then the function would just be
layout_set = function(...) {
private$layout <- if (is.function(..1)) ..1 else list(...)
}
which wouldn't return anything and be OK.
Am I understanding this correctly?
In Python, there is a convention to call "unused / do not care" arguments _
(https://hackernoon.com/understanding-the-underscore-of-python-309d1a029edc). Not sure if you can assign variables to _
in R or if R has that convention, but this codeblock might be easier for other folks to understand if it was written:
layout_set = function(...) {
private$layout <- if (is.function(..1)) ..1 else list(...)
# call layout_render() in order to [...] but don't return its response
_ <- private$layout_render()
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
anyway, this isn't blocking, just trying to understand things a bit better!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, no worries -- I appreciate your questions because they often lead me to a better understanding of the way Dash works.
This line confuses me a bit, although it might just be my misunderstanding of R. Where is
lay
being used?
- Is this setting it to the class?
- Does this also implicitly return
lay
?
The code (which I've since modified) does not set class attributes or implicitly return lay
since this line isn't the last one in the function. I've since wrapped layout_render()
inside a call to invisible
, which I think has the same effect as assignment to _
in Python. (I actually did not know about that, but it's a cool feature of which I should be aware.)
I've added a brief comment to explain what's happening here also.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, would be nice to understand at some point why this call is necessary (for that matter, I don't quite get why we have a nearly identical call on the Python side 😏) but thanks for making the intention clearer with invisible
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in f9c9174
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed a question or two here:
which would actually return
private$layout_render()
(since it's the last line of the function).
Yes, that's right.
But if we didn't need to call
private$layout_render()
, then the function would just be
Yep, got it -- this line basically says if the first argument of ...
is a function, assign it to layout
, otherwise wrap all the arguments into a list and assign that into layout
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice work! 💃 once you consider my comments
The proposed changes include
thecallback
method for Dash now uses theoutput, inputs, state, func
ordering for parameters, while previouslyoutput
was last; the change reflects the current Dash for Python callback signaturecallback
method for DashR now has a function signature that is closer to the Dash for Python API, with the caveat thatinputs
andstate
are unified into a singleparams
argumentfunc
argument, to pass the callback handler; R does not natively offer a Python-like decorator pattern, which is the current approach for specifying this function in Dash for Pythonassert_valid_callbacks
dash-renderer
to 18.0The current batch of examples will have to be updated to reflect the changes. I'm continuing to work on the code, but callbacks appear to function properly now.