GithubHelp home page GithubHelp logo

vue3 reactive input values about vuer HOT 6 OPEN

vue-r avatar vue-r commented on July 20, 2024
vue3 reactive input values

from vuer.

Comments (6)

timelyportfolio avatar timelyportfolio commented on July 20, 2024 1

valtio

After more thought, experimentation, and testing, I actually think valtio might be better than all mentioned above. I made a standalone build at valtio_standalone for easier testing without a modern (also complicated) JavaScript build toolchain.

example from above but with valtio

# experiment with Shiny inputValues and valtio
#   reference:
#     https://github.com/pmndrs/valtio
ui <- tagList(
  tags$head(
    tags$script(src = "valtio.js"),
  ),
  tags$div(
    tags$h3("Increment with JavaScript"),
    tags$span("Shiny: "),
    textOutput("reporterR", inline = TRUE),
    tags$span("JavaScript: "),
    tags$span(
      id = "reporterJS"
    ),
    tags$span("valtio computed: "),
    tags$span(
      id = "reporterComputed"
    )
  ),
  tags$div(
    tags$h3("Increment with R/Shiny"),
    tags$span("Shiny (used numeric input for convenience): "),
    numericInput(inputId = 'x2', label = "", value = 0),
    tags$span("JavaScript: "),
    tags$span(
      id = "reporterJS2"
    )
  ),
  tags$script(HTML(
"
$(document).on('shiny:connected', function() {

  // once Shiny connected replace Shiny inputValues with reactive Shiny inputValues
  Shiny.shinyapp.$inputValues = valtio.proxy(Shiny.shinyapp.$inputValues)

  // do our counter using Shiny.setInputValue from JavaScript
  Shiny.setInputValue('x', 0) // initialize with 0
  
  // test valtio computed
  valtio.addComputed(Shiny.shinyapp.$inputValues, {
    doubled: snap => snap.x * 2,
  })
  
  valtio.subscribeKey(Shiny.shinyapp.$inputValues, 'x', (v) => {
    console.log('javascript', v)
    document.getElementById('reporterJS').innerText = v
  })
  
  valtio.subscribeKey(Shiny.shinyapp.$inputValues, 'doubled', (v) => {
    console.log('javascript', v)
    document.getElementById('reporterComputed').innerText = v
  })

  setInterval(
    function() {
      Shiny.setInputValue('x', Shiny.shinyapp.$inputValues.x + 1) //increment by 1
    },
    1000
  )

  // react to counter implemented in Shiny
  valtio.subscribeKey(Shiny.shinyapp.$inputValues, 'x2:shiny.number', (v) => {
    console.log('shiny', v)
    document.getElementById('reporterJS2').innerText = v
  })

})
"
  ))
)

server <- function(input, output, session) {
  x2 <- 0  # use this for state of Shiny counter
  output$reporterR <- renderText({input$x})

  observe({
    invalidateLater(1000, session = session)
    x2 <<- x2 + 1 # <<- or assign required to update parent
    updateNumericInput(inputId = "x2", value = x2, session = session)
  })
}

shinyApp(
  ui = ui,
  server = server,
  options = list(launch.browser = rstudioapi::viewer)
)

from vuer.

JohnCoene avatar JohnCoene commented on July 20, 2024

This is genius: VueReactivity.reactive(Shiny.shinyapp.$inputValues), I did not know this was possible and indeed, it does not seem to break anything. I have not tested but perhaps it breaks namespaces (shiny::ns())?

Perhaps somewhat interestingly I was thinking along the same lines but rather differently; the idea of making shiny inputs reactive had not occurred to me. I was just exploring possibilities in private repo to essentially mimic reactiveValues JavaScript-side. It's still too early to share as there's not much functional yet but will send that your way when done.

  1. I might be completely wrong about this but sharing data from R server to JS/front-end can be made more efficient: two htmlwidgets using the cars dataset are serialised and stored twice.

  2. These are then not reactive. Ideally I would have the cars dataset as stored JavaScript object and a proxy of it in Shiny so I can dynamically interact with it and simply have it referenced for use in htmlwidgets and elsewhere. So I can very easily change that reactive (e.g.: add/remove rows) and see the changes reflected in all the htmlwidgets/shiny inputs that make use of that dataset.

I'm not sure I make complete sense.

from vuer.

JohnCoene avatar JohnCoene commented on July 20, 2024

I invited you to the repo in question (jsdata). I genuinely do not know if what it aims to achieve is even a good idea to begin with, feel free to tell me (and be honest about it too).

library(htmltools)
library(shiny)
library(jsdata)

random_string <- function(){
  paste0(sample(letters, 10), collapse = "")
}

string <- as_jsdata(random_string(), id = "string")

ui <- fluidPage(
  tags$head(
    tags$script(src = "https://unpkg.com/@vue/[email protected]/dist/reactivity.global.js"),
  ),
  useJsdata(),
  includeDataset(string),
  tags$script(
    HTML("datasets._datasets = datasets._datasets.map(set => VueReactivity.reactive(set));",
    "$(document).on('shiny:connected', function() {",
    "VueReactivity.effect(() => {
      document.getElementById('test').innerText = datasets.getDataset('string')
    })",
    "});")
  ),
  h1(id = "test")
)

server <- function(input, output){

  observe({
    invalidateLater(2000)
    new_string <- as_jsdata(random_string(), id = "string")
    update_dataset(new_string)
  })
}

shinyApp(ui, server)

My thinking was that this might make it somewhat easier to make existing htmlwidgets support reactivity.

from vuer.

JohnCoene avatar JohnCoene commented on July 20, 2024

(If you think this approach could work I can rename and move the package to this org)

from vuer.

timelyportfolio avatar timelyportfolio commented on July 20, 2024

@JohnCoene I really like the idea of jsdata but I think it likely operates best as a standalone. I don't know if you would want jsdata locked into vue-next reactivity. mobx would be another very good solution. I wonder if jsdata should provide a non-reactive foundation and then extensions could be built to supply the reactivity layer. Both mobx and vue reactivity are set for a new release soon.

One example @FrissAnalytics and I discussed was using vuex to manage data state in JavaScript with R doing the data manipulation.

from vuer.

timelyportfolio avatar timelyportfolio commented on July 20, 2024

@JohnCoene #4 and https://gist.github.com/timelyportfolio/edd70a7e40c54442aaccd5f529427fdc potentially related for jsdata purposes.

from vuer.

Related Issues (11)

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.