VTek

VTek

1st project here. Trying to attach a hook. I’ve spent hours logging everything I can think of to figure out why I can see my hook mount and even verify it mounts to the id I gave the element, but nothing I do will fire it.

Is there a way to trigger it from F12 console to confirm it’s even there? I tried this, but get true, and no console.log that I’m expecting:

hookElement.dispatchEvent(new CustomEvent("phx:update"))

TL;DR but here’s the now obnoxious dysfunctional hook (and yes I do send it when I new LiveSocket):

console.log("Hook definition reached");
let Hooks = {};
Hooks.IntroductionComplete = {
	mounted() {
	  console.log("IntroductionComplete hook mounted on " + this.el.id);
	  this.lastEventTime = 0;
	  this.setupEvent();
	  if (this.el) {
		this.el.dispatchEvent(new CustomEvent("phx:update"));
	  }
	  else console.log("No element found");
	},
	updated() {
	  console.log("IntroductionComplete hook updated");
	  this.setupEvent();
	},
	setupEvent() {
	  console.log("Before setting up introduction_complete event listener");
	  if (this.hasEventListener) return;
	  setTimeout(() => {
		this.hasEventListener = true;
		console.log("Setting up introduction_complete event listener");
		
		this.handleEvent("introduction_complete", () => {
		  console.log("Entering introduction_complete event handler");
		  console.log("Introduction complete event received");
		  this.revealTextArea();
		});
		console.log("After setting up introduction_complete event listener");
	  }, 300); // Adjust the delay for testing
	},
	revealTextArea() {
	  console.log("Revealing text area");
	  // Implement logic to reveal or enable the text area here
	}
  };

Showing Posts 1 to 10

regex.sh

regex.sh

You “dispatch” Hook by hooking it to an HTML element with id…

VTek

VTek OP

I’ve put it on divs and things at all different levels, root, app, component, sub-component, here’s where I have it now:

<textarea  id="introductionID" phx-hook="IntroductionComplete" ...

It doesn’t work, no matter where I put it.

I call it like this and console logs tell me it’s called:

IO.puts("sending introduction_complete event") 
push_event(socket, "introduction_complete", %{})

I’m so new at phx that I’m sure it’s something silly. I even stumbled on possibly using phx-update=“ignore” which seemed counterintuitive, but I’m stumped. AI is no help at all, it makes stuff up. So I’d hoped if I understood where the event is actually put in the dom I could see if it’s even there. AI just made stuff up:

“My previous suggestions regarding __phoenixHooks and __phxHookInstances were incorrect in terms of how you directly access hook instances on DOM elements in the browser console.”

Adzz

Adzz

What are you trying to do with the hook first? revealTextArea implies showing / hiding something which can be done more simply either with CSS and HTML (eg a <detail> component) or with the JS functions like toggle.

If you just want to get a hook working start with something very simple that adds a class to change the color of the element clicked. That way you can proceed in steps and see if the problem is defining the hook, or what the hook does.

It doesn’t work, no matter where I put it. I call it like this and console logs tell me it’s called

This implies that the hook is “hooked up” correctly, suggesting that what you have written in the hook doesn’t do what you expect it to do.

VTek

VTek OP

There is a server side delayed typing simulation response being pushed and that’s working. When the simulation completes I used push_event(socket, “introduction_complete”, %{}) to try to tell the dom that the process was complete and to show the textbox, but now all I have it doing is writing a console.log, which isn’t happening after sending the event.

I must misunderstand push_event, does it require that the client side rerender to trigger it? I’d thought liveview was controlling the dom and not the other way around. More than the specific functionality that’s what I’m trying to understand. Since pushing the event doesn’t trigger the console log I’m pretty sure I can’t change css or anything else really.

Thanks for the response!

LostKobrakai

LostKobrakai

Could it be that you’re not assigning this back to a socket?

socket = push_event(socket, "introduction_complete", %{})

push_event is not a sideeffect. The event is just queued and pushed once the socket is returned from the callback.

VTek

VTek OP

Thank you again! I’m sure that’s the concept I’m not getting, here’s the server side handler that triggers it, everything is working except for the hook:

def handle_info({:type_next_char, line_index, char_index, lines}, socket) do
    IO.puts("handle_info called with line_index: #{line_index}, char_index: #{char_index}")

    if line_index < length(lines) do
      line = Enum.at(lines, line_index)

      if char_index < String.length(line) do
        char = String.at(line, char_index)
        new_content = socket.assigns.typed_content <> char

        socket =
          socket
          |> assign(:typed_content, new_content)
          |> assign(:dummy_messages, [%{List.first(socket.assigns.dummy_messages) | content: new_content}])

        Process.send_after(self(), {:type_next_char, line_index, char_index + 1, lines}, 50)
        {:noreply, socket}
      else
        # Move to next line with a pause
        if line_index + 1 < length(lines) do
          new_content = socket.assigns.typed_content <> "\n"

          socket =
            socket
            |> assign(:typed_content, new_content)
            |> assign(:dummy_messages, [%{List.first(socket.assigns.dummy_messages) | content: new_content}])

          Process.send_after(self(), {:type_next_char, line_index + 1, 0, lines}, 1000)
          {:noreply, socket}
        else
          # Typing is complete
          socket = assign(socket, :typing_active, false)
          IO.puts("Typing simulation complete, sending introduction_complete event")
          push_event(socket, "introduction_complete", %{})
          {:noreply, socket}
        end
      end
    else
      {:noreply, socket}
    end
  end

Server console:


handle_info called with line_index: 1, char_index: 1
Typing simulation complete, sending introduction_complete event
LostKobrakai

LostKobrakai

That’s the incorrect part. You need socket = push_event(…).

VTek

VTek OP

yessir, that was it!

Entering introduction_complete event handler
app.js:65 Introduction complete event received
app.js:72 Revealing text area

I misunderstood the socket parameter to be enough.

VTek

VTek OP

out of curiosity, does the hook into the dom element itself get set in such a way that it could be triggered manually from the f12 console?

Adzz

Adzz

The hook is just JS that gets added to the bundle. It is available on liveSocket.hooks. in the console but whether you can “trigger” it really depends on what the hook does. In general though I wouldn’t recommend that approach because the app cares about how it gets triggered by phoenix, so that’s what you should test and see in dev.

Live socket is defined here https://github.com/phoenixframework/phoenix_live_view/blob/main/assets/js/phoenix_live_view/live_socket.js you can enable things like enableDebug which may help depending on what you want

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
ryanwinchester
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted” Version...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews