How do I page, a json result? Using scrivener

I am currently wanting to page a json result, starting from a function.

I know scrivener_ecto and scrivener_html.

However I am not able to make this pagination.
Can you help me??

below is my files

Controller

  def index(conn, _params) do
    result_list = listresult()
    render(conn, "index.html", result_list: result_list)
  end

The result of this function
and a json.

[
 %{
    e_tag: "\"5bd0dca2b5ba0510f5e39dc6f156ca97\"",
    key: "tttgz.txt",
    last_modified: "2018-01-03T19:56:56.000Z",
    size: "9049",
    storage_class: "STANDARD"
  },
  %{
    e_tag: "\"491ac9e6534f501728f48a1d400e174b-31\"",
    key: "tttgz2.txt",
    last_modified: "2018-01-03T19:57:08.000Z",
    size: "253552582",
    storage_class: "STANDARD"
  },
  %{
    e_tag: "\"6bc18d8a4f7f56783501ed610dbec22c-91\"",
    key: "tttgz3.txt",
    last_modified: "2018-01-03T20:04:41.000Z",
    size: "756647736",
    ...
  },
  %{
    e_tag: "\"3c32b2bb5f6a9f1c791b4a1a03b036bc-22\"",
    key: "tttgz4.txt",
    last_modified: "2018-01-03T20:25:56.000Z",
    ...
  },
  %{
    e_tag: "\"e560197c5396c82760453258af88756b-451\"",
    key: "tttgz5.txt",
    last_modified: "2018-01-03T20:30:15.000Z",
    ...
  },
  %{
    e_tag: "\"15e99185d86395c3cd2a4e38a9e342f8-27\"",
    key: "tttgz6.txt",
    ...
  },
  %{e_tag: "\"455b1d90c0a1d2c38f842d19f5c77609-36\"", ...},
  %{...}, 
  ...
]

always when I will access the page using the scrivener
he returns this error to me

protocol Scrivener.Paginater not implemented for [%{e_tag: "\"537f647fa84fd18d1e7ec1bb23e2fb40-1\""

So the question is?

How do I page this json result?

You can manually build %Scrivener.Page{} structs.

would you have an example to show me, how would it look?

Something like that:

%Scrivener.Page{
  entries: Enum.take(result, 10),
  page_number: 1,
  page_size: 10,
  total_entries: length(result),
  total_pages: Float.ceil(length(result) / 10)
}

Really that way, I was able to add pagination_links, without errors.
However, by clicking on button 2, 3, 4 …
It does not update the values.
Could you tell me what it can be?

def index(conn, _params) do
    result_list = listresult()

    test = %Scrivener.Page{
      entries: Enum.take(result_list, 10),
      page_number: 1,
      page_size: 10,
      total_entries: length(result_list),
      total_pages: Float.ceil(length(result_list) / 10)
    }


    render(conn, "index.html", test: test)
  end

You’ll need to make sure to update the Enum.take and page_number depending on which page you want to serve.

I believe this is the most difficult thing, right?

Being able to treat these values, because as I am not using Repo.paginate.

Not really. The page is in the params your controller action does receive (for page 2, …). Convert it to an integer and you got the page.

As you can see,

I put the page number, but how do I update the entries?

Whenever I click on the page numbers, the same values always remain.


 def index(conn, params) do
    result_list = listresult()
    number_page = Map.get(params, "page") |> String.to_integer()

    test = %Scrivener.Page{
      entries: Enum.take(result_list, 10),
      page_number: number_page,
      page_size: 10,
      total_entries: length(result_list),
      total_pages: Float.ceil(length(result_list) / 10)
    }

    IO.inspect(result_list)
    IO.inspect(params)
    render(conn, "index.html", test: test)
  end

You changed only one of the things I said need changing. You can’t just always Enum.take the first 10 items. You’ll need to the take the 10 items, which shall be shown for the current page.
result_list |> Enum.drop(number_page - 1 * 10) |> Enum.take(10)

So it worked.


  def index(conn, params) do
    result_list = listresult()
    number_page = Map.get(params, "page") |> String.to_integer()

    test = %Scrivener.Page{
      entries: result |> Enum.drop(number_page - 1 * 1) |> Enum.take(10),
      page_number: number_page,
      page_size: 10,
      total_entries: length(result_list),
      total_pages: Float.ceil(length(result_list) / 10)
    }

    IO.inspect(result_list)
    IO.inspect(params)
    render(conn, "index.html", test: test)
  end

When accessing from page 1 to 14 it works perfectly.
But when I access the page 15

http://localhost:4000/backups?page=15
Retorna este erro.

Request: GET /backups?page=15
** (exit) an exception was raised:
** (ArgumentError) ranges (first…last) expect both sides to be integers, got: 11…20.0
(elixir 1.10.4) lib/range.ex:63: Range.new/2
(scrivener_html 1.8.1) lib/scrivener/html.ex:511: Scrivener.HTML.page_number_list/4
(scrivener_html 1.8.1) lib/scrivener/html.ex:473: Scrivener.HTML.raw_pagination_links/2
(scrivener_html 1.8.1) lib/scrivener/html.ex:214: Scrivener.HTML._pagination_links/2

I managed to make it work, with your help
In this way

  def index(conn, params) do
    result_list = listresult()
    number_page = Map.get(params, "page") |> String.to_integer()

    IO.inspect(number_page)

    test = %Scrivener.Page{
      entries: result |> Enum.drop(number_page - 1 * 1) |> Enum.take(10),
      page_number: number_page,
      page_size: 10,
      total_entries: length(result_list),
      total_pages: Kernel.trunc(Float.ceil(length(result_list) / 10))
    }

    render(conn, "index.html", test: test)
  end

But I have a problem, every page that I go through.
I see that some files are repeated.
What do you think it can be?

Did you manage to make it work eventually?