FedeMadoery

FedeMadoery

How to use Pagination on Calculations? Do I need to handcraft my own Pagination macro?

I’m trying to do a pagination for a list of “messages” on a calculated field, so my structure is more or like the following one:

Channel Resource

defmodule Organizations.Channel do
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer,
    extensions: [
      AshGraphql.Resource
    ]

  require Ash.Query

  # Some other configs ...
 
  relationships do
    has_many :messages, Channels.ChannelMessage do
      private? true
      destination_attribute :channel_id
      api Channels
  end 

  actions do
    defaults [:create, :update, :destroy]

    # This one creates a PageOfChannels
    read :list do
      pagination countable: true,
                 required?: true,
                 offset?: true,
                 max_page_size: 10
    end

    read :read do
      primary? true
    end
  end

Channel Messages Resource

defmodule Channels.ChannelMessage do
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer,
    extensions: [
      AshGraphql.Resource
    ]

  # Some other configs ...

  actions do
    # This creates a  PageOfChannelMessages
    read :list do
      pagination countable: true,
                 required?: true,
                 offset?: true,
                 max_page_size: 10,
                 default_limit: 10
    end

    read :read do
      primary? true
    end
  end
  
  relationships do
    belongs_to :channel, Channels.Channel do
      allow_nil? false
      primary_key? true
    end
  end

With that said, I want to access my ChannelMessages, from the Channel resource, so I added a calculation for it, but I also want to paginate them using the same Type and structure (in this case PageOfChannelMessages) to share entities on the UI side with ApolloClient

So I did:

calculations do
    calculate :channel_messages, {:array, ChannelMessageUnion}, fn record, %{api: api} ->
      record = api.load!(record, :messages)

      record.messages
      |> Enum.map(&%Ash.Union{type: ChannelMessageUnion.struct_to_name(&1), value: &1})
    end

But with this calculation, my channel_messages is just an array with all the messages or just a trimmed array if I limit it, so I don’t see how I can calculate as a PageOf type since those types are not accessible or I don’t know how, so with this in mind, my question would be can I reuse the actual pagination of AshGraphQL o should I cook my own pagination to be able to re-use it across all my app (calculation and lists)

Marked As Solved

juno

juno

Wow. it’s working now. Awesome!

Looks like, in the module-based calculation, the return type must be a list of items. We got it to work with an inline calculation anonymous function. I see that there is a ticket for this specific issue in ash git repo Anonymous function calculations are inconsistent with module calculations · Issue #625 · ash-project/ash · GitHub

    calculate :channel_messages, MyApp.PageOfChannelMessages, fn record,
                                                                         %{
                                                                           offset: offset,
                                                                           limit: limit
                                                                         } = context ->

   ...Do your thing here

   {:ok, %{Page Of Channel Message info}
end do
      argument :offset, :integer do
        default 0
      end

      argument :limit, :integer do
        default 10
      end
end

I can’t thank you enough for helping us out.

Also Liked

FedeMadoery

FedeMadoery

Wow, thanks so much for the fast response…

I will give it a try and post the final result if it works or some other question if I get stuck! Thanks so much

zachdaniel

zachdaniel

Creator of Ash

I should really reproduce this in a test. However, I believe I’ve isolated the fix. Please try out ash_graphql main.

juno

juno

The calculation module works and also __typename is returning from the query. :+1:

Last Post!

juno

juno

Nice. it’s working now. I looked at your fix and it’s a simple one. Amazing…

Where Next?

Popular in Questions Top

baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement