How to show Tasks results in controller json

Hello, I need to send 3 requests when my user send me a request, for example

  def home_page(conn, _params) do
    aa = Task.async(fn -> :timer.sleep(100); IO.puts "hellow1" end)
    bb = Task.async(fn -> :timer.sleep(10000); IO.puts "hellow2" end)
    cc = Task.async(fn -> :timer.sleep(10); IO.puts "hellow3" end)
    conn
    |> put_status(200)
    |> json(%{name: aa, last_name: bb, mobile: cc})

end

but the controller Json converter can’t understand when these 3 request complete then shows them.

it shows me

    ** (Protocol.UndefinedError) protocol Jason.Encoder not implemented for %Task{owner: #PID<0.884.0>, pid: #PID<0.887.0>, ref: #Reference<0.470309852.650903556.197957>}, Jason.Encoder protocol must always be explicitly implemented.

now I want to create a map that can store 3 Task in itself and after completing requests then convert to Json and shows my user (like mobile application).

use Task.await https://hexdocs.pm/elixir/Task.html

2 Likes

I have tested it like this before

conn
    |> put_status(200)
    |> json(%{name: Task.await(aa), last_name: Task.await(bb), mobile: Task.await(cc)})

But I think I’m wrong, do you mean this?
and Task.await can’t show the results just writes :ok
like:

{
    "last_name": "ok",
    "mobile": "ok",
    "name": "ok"
}

your async tasks are not returning anything… eg try:
aa = Task.async(fn -> :timer.sleep(100); IO.puts "hellow1";"lets return this string" end)

3 Likes

Well, they return :ok, as thats what IO.puts/1 returns.

4 Likes