Search code examples
elixirphoenix-frameworkecto

Phoenix LiveView basic sorting of data for render


I want to sort this data by name. I am unsure how to do it via the view or from Repo. I know there is a Enum.sort() module, but I am not sure how to integrate it with the view code. I've played with it and can't seem to get it to work.

<%= for testbed <- @testbeds do %>
<tbody>
<tr class="transition duration-300 ease-in-out hover:bg-table_blue text white">
<td class="whitespace-nowrap px-6 py-2 font-medium"><%= testbed.name %></td>
<td class="whitespace-nowrap px-6 py-2"><%= testbed.version %></td>
<td class="whitespace-nowrap px-6 py-2"><%= testbed.note %></td>

</tr>
</tbody>
<% end %>

I found an example here: https://hexdocs.pm/elixir/Enum.html#sort/2

The database data I am working with looks like this:

[
  %App.TestBeds.TestBed{
    __meta__: #Ecto.Schema.Metadata<:loaded, "testbeds">,
    id: 12,
    developer: "none",
    name: "Gnot",
    note: "none",
    status: "Available",
    status_action_value: "1",
    version: "6.01",
    inserted_at: ~N[2023-03-05 11:30:56],
    updated_at: ~N[2023-03-12 19:45:29]
  },
  %App.TestBeds.TestBed{
    __meta__: #Ecto.Schema.Metadata<:loaded, "testbeds">,
    id: 13,
    developer: "none",
    name: "Grindy",
    note: "none",
    status: "Available",
    status_action_value: "0",
    version: "22",
    inserted_at: ~N[2023-03-08 16:36:15],
    updated_at: ~N[2023-03-12 23:05:25]
  },
  %App.TestBeds.TestBed{
    __meta__: #Ecto.Schema.Metadata<:loaded, "testbeds">,
    id: 14,
    developer: "zsdzdffffs",
    name: "Sonic",
    note: "none",
    status: "Taken",
    status_action_value: "0",
    version: "6.01",
    inserted_at: ~N[2023-03-12 09:17:43],
    updated_at: ~N[2023-03-12 23:32:49]
  }
]

When I apply the referenced function to this data directly I get an error:

Enum.sort(data, fn(x, y) -> x[name] > y[name] end)



** (SyntaxError) sandbox.ex:4:5: syntax error before: id
    |
  4 |     id: 12,
    |     ^
    (elixir 1.14.3) lib/code.ex:1260: Code.require_file/2
[Finished in 211ms]

I tried removing the meta property of each field and I get another error:

** (CompileError) sandbox.ex:2: App.TestBeds.TestBed.__struct__/1 is undefined, cannot expand struct App.TestBeds.TestBed. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code
    expanding struct: App.TestBeds.TestBed.__struct__/1
    sandbox.ex:2: (file)

When I minimize the data to look like the example below all works as expected.

data = [
  %{

    name: "Gnot",

  },
  %{

    name: "Grindy",

  },
  %{

    name: "Sonic",

  }
]

IO.inspect Enum.sort(data, fn(x, y) -> x[:name] > y[:name] end)

Solution

  • You can do it multiple way, on the repo level when you select the data, in your module where you prepare the data for the view with assign or directly in your view. For the last two options you can use the Enum.sort/sort_by.

    Example for sort_by I use personally:

    Enum.sort_by(testbeds, &(&1.name), :desc))