-
Notifications
You must be signed in to change notification settings - Fork 3
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
Minimally invasive result field fix #439
Conversation
@DivadNojnarg many thanks for the pointer
|
@nbenn you probably want to remove the |
@nbenn We need some safe gards whenever the data passed from one block to another is NULL and the block isn't a data block. serve_workspace(
stack1 = new_stack(new_dataset_block("BOD"), new_select_block("Time")),
stack2 = new_stack(new_result_block("stack1"))
) Something that also accounts for plot_block (since plot block are not transformed block and if you pass NULL data, you can enter the else if statement which would crash with a layer): reactive({
if (!is_valid$block) {
NULL
} else if (is.null(in_dat()) && !inherits(x, "transform_block") && !inherits(x, "plot_block")) {
browser()
evaluate_block(blk())
} else {
# Safe guard
if (is.null(in_dat())) return(NULL)
evaluate_block(blk(), data = in_dat())
}
}) You can test this by emptying data in the first block below: library(palmerpenguins)
library(ggplot2)
new_ggplot_block <- function(col_x = character(), col_y = character(), ...) {
data_cols <- function(data) colnames(data)
new_block(
fields = list(
x = new_select_field(col_x, data_cols, type = "name"),
y = new_select_field(col_y, data_cols, type = "name")
),
expr = quote(
ggplot(mapping = aes(x = .(x), y = .(y)))
),
class = c("ggplot_block", "plot_block"),
...
)
}
new_geompoint_block <- function(color = character(), shape = character(), ...) {
data_cols <- function(data) colnames(data$data)
new_block(
fields = list(
color = new_select_field(color, data_cols, type = "name"),
shape = new_select_field(shape, data_cols, type = "name")
),
expr = quote(
geom_point(aes(color = .(color), shape = .(shape)), size = 2)
),
class = c("plot_layer_block", "plot_block"),
...
)
}
serve_workspace(
stack1 = new_stack(new_dataset_block("penguins", "palmerpenguins"), new_ggplot_block("body_mass_g", "flipper_length_mm"), new_geompoint_block("species", "species"))
) |
Good points @DivadNojnarg, thanks! I was suspecting that there might be a bit of fallout with this (Maybe the "minimally-invasive" part of the title was a bit misleading..) |
Yes I prefer NULL over having to specify different empty constructors. |
@DivadNojnarg do you know why we do Line 227 in 061ac78
in the first place? Wouldn't this better be something like (Side remark: the logic in Line 214 in 061ac78
should be exactly the same, no?) For the other issue you point out:
High-level, I feel the problem is somewhere else: if you empty the dataset selection, the datase block should turn "invalid" and the select block should then not evaluate. So we'd need to factor in |
Does this happen, i.e. that we have |
The first point is likely an accidental removal. They should have the same conditions. Second point: something like: reactive({
if (!is_valid$block || (!is.null(is_prev_valid()) && !isTRUE(is_prev_valid()))) {
NULL
} else if (is.null(in_dat()) && !inherits(x, "transform_block") && !inherits(x, "plot_block")) {
evaluate_block(blk())
} else {
evaluate_block(blk(), data = in_dat())
}
}) |
In the update block observer, we also may want to prevent to update the block if the previous one is invalid: obs$update_blk <- observeEvent(c(r_values(), in_dat(), is_prev_valid()),
{
if (!is.null(is_prev_valid()) && !isTRUE(is_prev_valid())) return(NULL)
...
}) An even better alternative would be to avoid triggering the event at all. However, with our current logic, you can't just do req(is_prev_valid()) since for data block is_prev_valid() is always NULL, and this would block the whole chain. That said, it could be rewritten a bit like so: # I must admit this thing should be done with different S3 server methods, but as we don't have them anymore ...
update_blk_trigger <- reactive({
if (inherits(x, "data_block")) {
r_values()
} else {
c(r_values(), in_dat(), req(is_prev_valid()))
}
})
obs$update_blk <- observeEvent(update_blk_trigger(), { ...}) |
For my two example cases, this works. Have not checked more "exotic" scenarios such as plot blocks etc.