eddyraz

eddyraz OP

I also tried this and nothing, Iĺl post the liveview tree of livecomponents and who calls who, and also the code so youĺl have more context.

0
Post #11
eddyraz

eddyraz OP

I have a live a liveview named opac who dynamically renders a navbar component , then in case user is succesfully authenticated renders a searchbar component, and if not then renders a login component, and last a footer component all that as shown below in the render function of opac liveview.

@impl true
  def render(assigns) do
    ~H"""
    <div>
      <section>
        <div>
          <%= live_component(@socket, DedalosPhoenixWeb.NavbarLive) %>
        </div>

        <%= if @is_authenticated == false do %>
          <div>
            <%= live_component(@socket, DedalosPhoenixWeb.LoginLive) %>
          </div>
        <% else %>
          <div>
            <%= live_component(@socket, DedalosPhoenixWeb.SearchBarLive, id: 3) %>
          </div>
        <% end %>
        <div>
          <%= live_component(@socket, DedalosPhoenixWeb.FooterLive) %>
        </div>
      </section>
    </div>
    """
  end

in the login component render function i check the credentials of the login form in a function as stated in the form tag
<form phx-submit="check_login_credentials" id="login_form">

the check_login_form function in opac (the login_view parent ) says this:

@impl true
  def handle_event("check_login_credentials", params, socket) do
    login_token = process_token_request(params["user_name"], params["password"], socket)

    send_token_to_browser(socket,params,login_token)  

  end

and the function send_token_to_browser states that:

  @impl true 
  def send_token_to_browser(socket, params, login_token) do

    
    if login_token do
          {:noreply, push_event(socket, "save_login_token", %{payload: login_token})}
      
      socket = socket |> assign(:is_authenticated, true)    
      {:noreply, assign(socket, params: params)}
    else
      {:noreply, assign(socket, params: params)}
    end

    end

and in the /assets/js/app.js file in the hooks section I put this as suggested by mcrumm:

let hooks = {}

hooks.saveLoginToken = {
    mounted() {
    	this.handleEvent("save_login_token", ({payload}) => {
       console.log("received payload", payload
   })	



  },    
};

also in the socket declaration I stated as recommended by the docs:

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}, hooks: hooks})

I hope this shed more light on my problem, I keep digging looking for clues of why this does not work. Thanks in advance.

0
Post #12
mcrumm

mcrumm

Phoenix Core Team

The problem is in send_token_to_browser:

Note that push_event returns a modified socket struct- the event is not pushed to the client until you return from the LiveView callback. You are not receiving the event on the client because you are not returning the socket struct containing the event.

2
Post #13
mcrumm

mcrumm

Phoenix Core Team

Also, double-check the hook code I shared- you need to modify the callback’s function signature, too :slight_smile:

0
Post #14
eddyraz

eddyraz OP

edited

0
Post #15
eddyraz

eddyraz OP

Thanks so much,

I put it this way, and it worked:

@impl true
  def handle_event("check_login_credentials", params, socket) do
    login_token = process_token_request(params["user_name"], params["password"], socket)

    send_token_to_browser(socket, params, login_token)
  end

  @impl true
  def send_token_to_browser(socket, params, login_token) do
    if login_token do
      socket = socket |> assign(:is_authenticated, true)
      {:noreply, push_event(socket, "save_login_token", %{payload: login_token})}
    else
      {:noreply, assign(socket, params: params)}
    end
  end
1
Post #16
— All posts loaded —