willc0de4food

willc0de4food

Automatically chart async data in liveview without user interaction

Howdy,

I’m struggling with something that seems like it should be simple. I would like to fetch some data via async when the page loads, and then once loaded, graph that data with Highcharts. Everything I’ve read has indicated that you need to setup a hook that will allow you to pass the data from the server to the JS, and you use a handle_event to trigger push_event() with the data. I don’t have a user interaction to trigger the handle_event, I just want the graph to load once the data is ready. I tried adding the push_event() to handle_async , but nothing happens in the JS hook. I have added a dbg() line to verify that the data is being received in the handle_async.

What am I missing? :sweat_smile:

Some code:

def mount() do
  ...
  |> start_async(:points, fn -> Tokens.generate_chart_data() end)
  ...
end

  def handle_async(:points, {:ok, points}, socket) do
    dbg(points)
    {:noreply, push_event(socket, :points, %{points: points})}
  end

  def render(assigns) do
    ~H"""
    ...
    <div class="mt-4 flex flex-row w-full">
        <div id="graph" phx-hook="Graph"></div>
    </div>
    """
  end
var Hooks = {};
Hooks.Graph = {
  mounted() {
	logToConsole('mounted');
  },
  updated() {
  	logToConsole('updated');
  	this.handleEvent("points", ({points}) => logToConsole(points);
  }
}
let logToConsole = (action) => {
	console.log('*********************', action);
}

Marked As Solved

willc0de4food

willc0de4food

Update: I got it working without hooks! It was as straight forward as it seemed like it should be, I just didn’t know what I didn’t know. The final working product:
live view:

  def mount(params, _session, socket) do
    ...
    socket =
      socket
      ...
      |> start_async(:points, fn -> Tokens.generate_chart_data() end)
    {:ok, socket}
  end

  def handle_async(:points, {:ok, points}, socket) do
    {:noreply, push_event(socket, "graph", %{points: points})}
  end

  def render(assigns) do
    ~H"""
      ...
          <div id="graph"></div>
    """
  end

app.js:

window.addEventListener(
  "phx:graph",
  e => {
  	if (e.detail?.points) {
  		Highcharts.chart('graph', { ... });
  	}
  }
)

That’s it :slightly_smiling_face:

Also Liked

cmo

cmo

Firstly, you need to put this.handleEvent("points", ({points}) => logToConsole(points); in mounted.

You can set it up so that the process receives a message every x seconds, which you handle in handle_info and can trigger the start_async from there.

You can send the message every x seconds with :erlang.send_interval(Time, Destination, Message) or trigger it each time you process the message in handle_info/handle_async. That is Process.send_after(...)), called once in mount and then again in handle_info

If the data is on some publication you could subscribe to that in your liveview.

cmo

cmo

I’d still go with a hook as often you want to dispose of the chart in destroyed and/or modify it in update and push the event to the specific chart.

So sorry for the timer stuff, I had realtime chart on the brain from a post on the discord and conflated the two.

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: &lt;h1&gt;Create Post&lt;/h1&gt; &lt;%= ...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New

Other popular topics Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29703 241
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52774 488
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36432 110
New
Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 127536 1222
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement