Search code examples
elixirphoenix-live-view

no function clause matching in ProyectWeb.PageLiveView.handle_info/2


I don't know how I can match my asynchronous function and my handle_info

this code works:

def order_month() do
    Task.async(fn ->
      (1..12)
      |> Enum.map(fn a -> %{months: a} |> Map.put(:order_months, Proyect.BuyHandler.order_month(a |> Integer.to_string()) 
      |> Enum.map(fn m -> m |> Proyect.BuyHandler.get_opc() end))end)
      end)


  end

my intention is to receive it this way:

def handle_info({_ref, %{months: month, order_months: order_months}}, socket) do
   {:noreply, assign(socket, %{months: month, order_months: order_months} )}

Solution

  • Task.async/1 is designed to yield results with Task.await/2.

    Whether you want to receive results back with handle_info/2, you should explicitly send the results from the spawned (e. g. with Kernel.spawn/1) process to the parent process.

    You have not shown the code of Proyect.BuyHandler.get_opc/1, but if we assume it does a simple transformation, we might send the message from there (Task.start/1 should be used instead of Task.async/1 in such a case to start the process unlinked.) Somewhat along these lines would work.

    def order_month(pid) do
      Task.start(fn ->
        (1..12)
        |> Enum.map(fn a ->
          %{months: a,
            order_months: Proyect.BuyHandler.order_month("#{a}")}
        end)
        |> Enum.map(&Proyect.BuyHandler.get_opc/1)
        # ⇓⇓⇓⇓⇓ THIS ⇓⇓⇓⇓⇓
        |> Enum.each(&send(pid, &1))
      end)
    end
    

    handle_info/2 itself should probably have a signature def handle_info(%{}}, socket) in such a case.