Hello,
Do y’all know of a way to talk to a USB device from a Phoenix web app?
Hello,
Do y’all know of a way to talk to a USB device from a Phoenix web app?
Look into the Web USB API. (It doesn’t have great compatibility)
Maybe the nerves project has something for this? And also what is the use case?
From a Phoenix web app I want to talk to a ledger nano s/x ( ledger nano s and x are crypto currency hardware wallets).
Here is a JS lib for what I’m trying to do: GitHub - LedgerHQ/ledgerjs: Ledger's JavaScript libraries
If you’re trying to talk to the device from the browser, then what I would do is just use the JavaScript library for my web app, and if I need to integrate it with LiveView, I’d use JS hooks. I don’t think there is a better way to do that for someone accessing your phoenix app via a browser since what you’re doing is interacting with the client-side hardware.
So via the JS hooks I can call the ledger js library from my Phoenix code and have it do all the things I need?
I got a simple example working where i can click a button and it pushes an event to a Hook and then said hook does something and then push an event back to the liveview. I am curious if this type of pattern is acceptable.
My end goal is to click a button - have this library do its thing GitHub - LedgerHQ/ledgerjs: Ledger’s JavaScript libraries and then send the results back to my liveview.
So in short i want to click a button in a liveview - have some JS do its thing - and then get the results back in my liveview
Here is my app.js hook code
let Hooks = {};
Hooks.Counter = {
mounted() {
this.handleEvent("counter", ({ counter }) => {
alert(counter)
this.pushEvent('inc_2', { counter: counter + 1 })
})
}
}
Here is my counter_live.html.heex
Counter: <%= @counter %>
<button id="test" phx-hook="Counter" phx-click="inc_1">+</button>
Here is counter_live.ex
defmodule MyappWeb.CounterLive do
# In Phoenix v1.6+ apps, the line below should be: use MyAppWeb, :live_view
use HelloWeb, :live_view
def mount(_params, _, socket) do
{:ok, assign(socket, counter: 0)}
end
def handle_event("inc_1", _session, socket) do
{:noreply, push_event(socket, "counter", %{counter: socket.assigns.counter})}
end
def handle_event("inc_2", %{"counter" => counter}, socket) do
{:noreply, assign(socket, counter: counter)}
end
end
You could have the button directly do the thing and send inc_2
to the backend without sending inc_1
at all, that lets you skip a request cycle and makes it snappier. Unless you want the inc_1
step to actually do something on the backend other than send an event back.
I think this pattern is where ill land. I believe ill need the backend to build the payload that will be sent to the javascript library.