Shiny Input

The idea in this example is not to just reproduce the functionalities of a shiny application with ambiorix but also to do so using the same technology: websockets, even though one may not want to go about it this way in ambiorix.

Shiny

library(shiny)

ui <- fluidPage(
  textInput("inp", "Text input value"),
  actionButton("submit", "Submit"),
  textInput("out", "Set by server")
)

server <- function(input, output, session){
  observeEvent(input$submit, {
    updateTextInput(session, "out", value = input$inp)
  })
}

shinyApp(ui, server)

Here we build a shiny application that takes a text input, upon clicking a button sends that value to the server which uses it to update another text input.

Ambiorix

The easiest way to setup the structure for this application (with websocket support) is to use the CLI or ambiorix.generator::create_basic() from the ambiorix.generator package.

The server only responds to one request to the homepage (/) to which it sends an HTML file we shall cover next. The server also listens to websocket messages named textValue which it sends back as another message with a different name: setTextValue.

library(ambiorix)

app <- Ambiorix$new()

# serve static files
app$static("assets", "static")

# homepage
app$get("/", \(req, res){
  res$send_file("templates/home.html")
})

# websocket 
app$receive("textValue", \(msg, ws){
  ws$send("setTextValue", msg)
})

app$start()

In the HTML we use ambiorix’ websocket library to listen to messages named setTextValue sent from the server and use it to set the input value of text input name2.

We also have a sendValue() function on a submit button to collect the value of the first input and send it to ambiorix’ server.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="static/style.css">
  <script src="static/ambiorix.js"></script>
  <script>
    var wss = new Ambiorix();
    wss.receive("setTextValue", function(msg){
      document.getElementById('name2').value = msg;
    });
    wss.start();
  </script>
  <title>Ambiorix</title>
</head>
<body>
  <h1 class="brand">Ambiorix</h1>
  <label for="name">Give the text input value</label>
  <input type="text" id="name" name="name">
  <button onclick="sendValue();">Send a message</button>
  <br>
  <br>
  <br>
  <label for="name">Text input below is set by server</label>
  <input type="text" id="name2" name="name2">
  <script>
    sendValue = function(){
      let val = document.getElementById('name').value;
      Ambiorix.send('textValue', val)
    }
  </script>
</body>
</html>