microsoftgraph/msgraph-sdk-php

V2 pagination with getValue unclear

uncaught opened this issue · 3 comments

The documentation Get a collection of items mentions paging, but the example and code are not entirely clear here.

The call $messages->getValue() from the example would return a native php array type.

Is that array already filled with all items from all pages? Is that guaranteed? Or do I only get a single page here?


On a side note, it might have been better to return a \Generator that can be iterated over, independent on the page size, that will simply call the next page when it's its turn.

Hi @uncaught , thanks for trying out the SDK.

Is that array already filled with all items from all pages?

No, it only contains a single page.

To get the items on all pages, use the PageIterator, which is described in the next section titled Paging through a collection

Thanks for the feedback on using the \Generator.

Thank you for your reply!

But so, basically, for every collection, using getValue() is potentially risky because I am in no way forced to deal with pagination. Should you not deprecate this then in favor of a safer method?

My solution is a wrapper around the PageIterator for now:

  public static function iterateCollection(GraphServiceClient $client, Promise $promise): \Generator {
    $pageIterator = new PageIterator($promise->wait(), $client->getRequestAdapter());
    while ($pageIterator->hasNext()) {
      $pageItems = [];
      $pageIterator->iterate(function ($item) use (&$pageItems) {
        $pageItems[] = $item;
      });
      foreach ($pageItems as $pageItem) {
        yield $pageItem;
      }
    }
  }

Obviously this could be implemented cleaner inside the PageIterator without using a callback, but I didn't want to create a fork for this ;)

Example call:

/** @var \Iterator<int, Event> $collection */
$collection = GraphFactory::iterateCollection($graph, $graph->me()->calendarView()->get($config));
foreach ($collection as $event) {
  //...
}