1.8 Alpha 2 - Pagination

Continuing the discussion from Display Search API returns only 10 rows - 1.8.0-alpha2:

Seems we are not getting something correct. We applied this fix. When we send start=5 and size=5 we get this back:

string 'https://domain.com/xibo18alpha/web/api/library?start-46&length=51; rel=“prev”, https://domain.com/xibo18alpha/web/api/library?start=0&length=51; rel=“first”

Any Ideas? Prev seems to be -510+1, and next seems to be 510+1

UPDATE: Problem was obvious once posted. size=5 should be length=5.

Our other problem seems to be that the length when passed is being ignored. If we set the length to 5 we get more then that.(Hard to say where it is stopping as in the current trial we only have 7 entries matching our media search.)

The grids in the Web UI use the same syntax for start and length so I believe that is working generally.

There is another obvious problem in the code - i’m an idiot for not spotting it:

// Is there a next page?
if ($start + $size < $totalRows)
    $linkHeader .= '<' . $url . '?start' . ($start + $size * 2) . '&length=' . $size . '>; rel="next", ';

// Is there a previous page?
if ($start > 0)
    $linkHeader .= '<' . $url . '?start' . ($start - $size) . '&length=' . $size . '>; rel="prev", ';

There should be an = in the string concatenation, i.e. ?start=' . ($start

I really should have spotted that :unamused: - :bug:

Line 74 should also be “length” and not “size” as you have indicated.

I don’t know why you have a length of 51 in those links - it should always be exactly what you’ve provided - i.e. 5. Previous should be start - length and Next should be start + length + length. Make sense?

I applied the last bug fix. We don’t get length 51 anymore.

But now when we pass start=0 and length=5 we get this:

array (size=1)
  0 => string '<https://domain.com/xibo18alpha/web/api/library?start=20&length=10>; rel="next", <https://domain.com/xibo18alpha/web/api/library?start=0&length=10>; rel="first"' (length=170)

So length looks to be ignored and defaulting to 10, next for some reason is starting at 20, but first looks right.

In ApiView.php, if I remove the

* 2

I get what I would think I should get unless I am missing something. But the length we are passing seems to be ignored. If I pass start=0 size=5 length=5, without the * 2, I get back:

array (size=1)
  0 => string '<https://domain.com/xibo18alpha/web/api/library?start=0&length=51>; rel="first"' (length=84)

Re-downloaded the file from github and same problem.

We looked and looked at our code and the Xibo code. Nothing says that a “1” should be being added anywhere. So we decided to through some garbage on the end of the api url call:

api/library?start=0&size=5&na=

To our surprise we got back:

array (size=1)
  0 => string '<https://domain.com/xibo18alpha/web/api/library?start10&length=5>; rel="next", <https://domain.com/xibo18alpha/web/api/library?start=0&length=5>; rel="first"' (length=167)

The Start is missing the “=”, we know how to fix that. But “next” should not be 10 for the start if the size/length is 5.

UPDATE: Even though the API returns the correct length on the links, the returned results seem to be everything from “Start” to the last matching record. It does not seem to obey the length.

Can you post that little block of code in ApiView.php so I can see what you have now?

The parameter should always be length=, not size= - that was the root cause of my confusion anyway.

// Are we a grid?
if ($this->get('grid') == true) {
    // Set the response to our data['data'] object
    $grid = $this->get('data');
    $response = $grid['data'];

    // Total Number of Rows
    $totalRows = $grid['recordsTotal'];

    // Set some headers indicating our next/previous pages
    $start = Sanitize::getInt('start', 0);
    $size = Sanitize::getInt('size', 10);

    $linkHeader = '';
    $url = $app->request()->getUrl() . $app->request()->getPath();

    // Is there a next page?
    if ($start + $size < $totalRows)
        $linkHeader .= '<' . $url . '?start=' . ($start + $size) . '&length=' . $size . '>; rel="next", ';

    // Is there a previous page?
    if ($start > 0)
        $linkHeader .= '<' . $url . '?start=' . ($start - $size) . '&length=' . $size . '>; rel="prev", ';

    // The first page
    $linkHeader .= '<' . $url . '?start=0&length=' . $size . '>; rel="first"';

    $app->response()->header('X-Total-Count', $totalRows);
    $app->response()->header('Link', $linkHeader);
} else {
    // Set the response to our data object
    $response = $this->get('data');
}

I think I am just totally confused now. :dizzy_face: If you wouldn’t mind helping me un-confuse my head…

Is the block of code I posted correct?

When you say “The parameter should always be length=, not size=”, is that referring to the the parameter being passed to the api? I believe that is what you meant; I tried it and got mixed results on that as well.

If I pass start=0 and size=5, I get back the correct number of results from the API (5), but the links for next and previous default to 10 and not the size passed.

If I pass start=0 and length=5, I get back the default of 10 results(Not 5) from the API, but the size of 5 on links for next and previous are correct.

UPDATE: Fixed.

Changing
$size = Sanitize::getInt('size', 10);
to

$size = Sanitize::getInt('length', 10);

Seems to have fixed the problem for us.

1 Like

That is exactly the change you needed to make - so I am pleased that worked.

1 Like