How to paginate the products?

Solved
DaviAmaral
Excursionist
25 4 3

How to do that?

 

When I am trying to do that not all the products are showing. 

 

When I do the: 

/admin/api/2019-07/products/count.json

 

I am receiving this message: 

{"count":258}

 When I try to the pagination: 

/admin/api/2019-07/products.json?limit=250&page=1

 

I am receiving this message: 

{"errors":{"page":"page cannot be passed. See https:\/\/help.shopify.com\/api\/guides\/paginated-rest-results for more information."}}

 

Accepted Solution (1)

Accepted Solutions
DaviAmaral
Excursionist
25 4 3

This is an accepted solution.

I created a solution for doing this:

.../products.json?direction=next&last_id=8151827848&limit=250&order=id

where 8151827848 was the last product in my previous consult.

I don't know if we ware talking about. 

I hope it is helpful.   

 

Tks guys! 

View solution in original post

Replies 13 (13)
Busfox
Shopify Staff
Shopify Staff
628 49 106

Hi @DaviAmaral,

 

Did you view the url in the error message? It should show how to use cursors to paginate through products. Essentially, you need to look for the link header, which will contain a link for the next page and the previous page. You would fetch the next page by making a request to that url.

 

Cheers,

Andrew | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

DaviAmaral
Excursionist
25 4 3

Yes, I forgot to put the second part of the question:

 

https://{shop}.myshopify.com/admin/api/2019-07/products.json?page_info={page_info}&limit=250

 

Really don't understand what {page_info} means.

 

"A unique ID used to access a certain page of results. The page_info parameter can't be modified and must be used exactly as it appears in the link header URL."

 

How can I get this unique ID.

Busfox
Shopify Staff
Shopify Staff
628 49 106

Hi @DaviAmaral,

 

The page_info is provided in the link header value. Essentially, we give you the url to make a GET request at to receive the next page of results. You don't need to provide any additional parameters.

Andrew | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

DaviAmaral
Excursionist
25 4 3

This is an accepted solution.

I created a solution for doing this:

.../products.json?direction=next&last_id=8151827848&limit=250&order=id

where 8151827848 was the last product in my previous consult.

I don't know if we ware talking about. 

I hope it is helpful.   

 

Tks guys! 

ITAgnesmeyer
New Member
2 0 0

what a bad solution.
There is a pagination, but it cannot be used.
So if I want to use the built-in pagination, I have to search an HTML tag in the header for a page_info entry.
Unfortunately, this page_info only shows the current page.
The solution with the last number has the disadvantage that it cannot be used with since_id.
This means you cannot paginate if you use since_id.

 

 

DaviAmaral
Excursionist
25 4 3

Just to be clear, I don't work In Shopify, I am just a User like you trying to help others users.

And trying to help you, try that:

...admin/api/2019-10/products.json?direction=next&last_id=81732365528173236552&last_value=3672573149263&limit=50&order=id

 

To figure out that, you can look at how works the pagination in the Shopify admin.

 

 

 

 

 

 

ITAgnesmeyer
New Member
2 0 0

I also didn't want to make your approach bad.

But the developers at Shopify only acted a little impractical.

Pagination should make life easier for API users and not more difficult 😞

Thanks again for your approach.

With your approach you can of course work.

 

 

KillerBee3453
New Member
2 0 1

 Is "Direction" a valid query parameter and if so where did you find it at? I look through the API and I don't see any of this things listed there 

jw_pei
New Member
13 0 0

jw_pei_0-1613716186369.png

 

DaviAmaral
Excursionist
25 4 3

try this=>  ?limit=250&direction=next&order=id

after get the last id from the firest request and add this in the url ?limit=250&direction=next&order=id&last_id=841542238383

ahmadkarim
Tourist
3 0 1

I am not sure what you mean by this:


@Busfox wrote:

Hi @DaviAmaral,

 

The page_info is provided in the link header value. Essentially, we give you the url to make a GET request at to receive the next page of results. You don't need to provide any additional parameters.


I am making a CURL request to this API method: https://shopify.dev/docs/admin-api/rest/reference/products/product#index-2020-10

How do I retrieve the link header value? 

I want to paginate the products using Previous and Next links on my page

Tenarius
Excursionist
15 1 2

Hi,

 

why not using the official documentation: https://shopify.dev/api/usage/pagination-rest

 

You can use the response header to get links for next and previous pagination. In my case (PHP) I extracted the "page_info" field to manually manage my frontend data table.

 

/**
 * Paginate Shopify Responses
 * 
 *  array
 *  array
 * 
 * 
 *  array
 * 
 */
public function paginateShopifyResponse(array $responseHeaders, array $responseBody): array
{

	$data = [];

	if(array_key_exists('Link', $responseHeaders)){

		$link = $responseHeaders['Link'][0]; // get the wohle link
		
		$links = explode(",", $link);

		$tobeReplace = ["<",">",'rel="next"',";",'rel="previous"'];
		$tobeReplaceWith = ["","","",""];

		foreach ($links as $link) {
			$link_type  = strpos($link, 'rel="next') !== false ? "next" : "previous";
			parse_str(parse_url(str_replace($tobeReplace, $tobeReplaceWith, $link), PHP_URL_QUERY), $op);
			$data[$link_type] = trim($op['page_info']);
		}
	}

	$data['resource'] =  (is_array($responseBody) && count($responseBody) > 0) ? array_shift($responseBody) : $responseBody;

	return $data;
}

 

This function returns an array with the body recource and the next and previous "page_info". (Additionally I added an data-counter of my customers):

 

return [
	'customers' => $customers['resource'], 
	'count' => $this->countCustomers(), //count all existing customers
	'next' => isset($customers['next']) ? $customers['next'] : null,
	'prev' => isset($customers['previous']) ? $customers['previous'] : null
];

 

In later requests, you only need as data-field the "page_info" with the content of "prev" or "next" and you will get your desired data. Don´t forget to specify the "limit"-field, otherwise it makes not sense. 😉

 

It´s really a bit tricky to get this, if you´re a newbe but i got a lot of help from the community.

 

Some greets and some success,

Tenarius

DaviAmaral
Excursionist
25 4 3

I created this some months ago, worked for what I wanted...

 you can delete the excel parts and change checkouts.json' for 'checkouts.json'

 

 

 

    public function testepagination(){
        ini_set('max_execution_time', 99999999);
        $limit = 250;
        $limit = '?limit=' . $limit;
        $merged = array();
        $next_page = '';
        $last_page = false;
        $i=0;
        $no_pagination = false;
        $page_info = '';
        $username = 'yourapikey';
        $password = 'yourapipassword';
        $shop = 'youshopify';
        $api = 'api/2021-10/';
        $created_at_min = '2020-01-01T00:00:00-00:01';
        $created_at_max= '2020-12-31T11:59:59-00:01';
        $auth = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/admin/' . $api  ;
        $request = $auth . 'checkouts.json'. '?created_at_min='.$created_at_min.'&created_at_max='.$created_at_max;
        $fields = '';
        $endpoints = '';
        $x=1;
        $j=1;
        $data[0] = ['id', 'token', 'cart_token', 'email',  'buyer_accepts_marketing', 'created_at',  'updated_at',  'referring_site', 'taxes_included',  'currency', 'first_name', 'address1',  'address2', 'city',  'zip', 'province', 'country', 'last_name',  'country_code', 'province_code',  'name','abandoned_checkout_url'  ];

        $data2[0] = ['checkout_id', 'key', 'destination_location_id','fulfillment_service', 'gift_card', 'origin_location_id', 'presentment_title',  'presentment_variant_title',  'product_id',  'sku', 'title',   'variant_id',    'variant_title',   'vendor', 'line_price', 'price', 'quantity'];
        while(!$last_page) {
            sleep(1);
            $url = $request . $limit . $fields . $endpoints . $page_info;
            echo ($url. '<br>');
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$headers) {
                $len = strlen($header);
                $header = explode(':', $header, 2);
                if (count($header) >= 2) {
                    $headers[strtolower(trim($header[0]))] = trim($header[1]);
                }
                return $len;
            });
            $result = curl_exec($curl);
            $array = json_decode($result);         
            if (isset($array->checkouts)){
                foreach ($array->checkouts as $key=>$value){
                                $data[$j] = [$value->id,
                                            $value->token,
                                            $value->cart_token,
                                            $value->email,
                                            $value->buyer_accepts_marketing,
                                            $value->created_at,
                                            $value->updated_at,
                                            $value->referring_site,
                                            $value->taxes_included,
                                            $value->currency,
                                            (isset( $value->shipping_address->first_name  )) ? $value->shipping_address->first_name   : '',
                                            (isset( $value->shipping_address->address1  )) ? $value->shipping_address->address1   : '',
                                            (isset( $value->shipping_address->address2  )) ? $value->shipping_address->address2   : '',
                                            (isset( $value->shipping_address->city  )) ? $value->shipping_address->city   : '',
                                            (isset( $value->shipping_address->zip  )) ? $value->shipping_address->zip   : '',
                                            (isset( $value->shipping_address->province  )) ? $value->shipping_address->province   : '',
                                            (isset( $value->shipping_address->country  )) ? $value->shipping_address->country   : '',
                                            (isset( $value->shipping_address->last_name  )) ? $value->shipping_address->last_name   : '',
                                            (isset( $value->shipping_address->country_code  )) ? $value->shipping_address->country_code   : '',
                                            (isset( $value->shipping_address->province_code  )) ? $value->shipping_address->province_code   : '',
                                            (isset( $value->shipping_address->name  )) ? $value->shipping_address->name   : '',
                                            (isset( $value->abandoned_checkout_url  )) ? $value->abandoned_checkout_url   : ''
                                        ];
                            $j++;                                      
                           
                            foreach ($value->line_items as $key=>$value2){
                                $data2[$x] = [$value->id,
                                                    $value2->key,
                                                    $value2->destination_location_id,
                                                    $value2->fulfillment_service,
                                                    $value2->gift_card,
                                                    $value2->origin_location_id,
                                                    $value2->presentment_title,
                                                    $value2->presentment_variant_title,
                                                    $value2->product_id,
                                                    $value2->sku,
                                                    $value2->title,
                                                    $value2->variant_id,
                                                    $value2->variant_title,
                                                    $value2->vendor,
                                                    $value2->line_price,
                                                    $value2->price ,
                                                    $value2->quantity];
                                $x++;    
                            }    
                }  
            }
                echo ("page" . $i++ . '<br>');
                curl_close($curl);
   
            if(isset($headers['link'])) {
                $links = explode(',', $headers['link']);
   
                foreach($links as $link) {
                    $next_page = false;
                    if(strpos($link, 'rel="next"')) {
                        $next_page = $link;
                    }
                }
   
                if($next_page) {
                    preg_match('~<(.*?)>~', $next_page, $next);
                    $url_components = parse_url($next[1]);
                    parse_str($url_components['query'], $params);
                    $page_info = '&page_info=' . $params['page_info'];
                    $request = $auth . 'checkouts.json';
                    echo $params['page_info'] . '<br>';
                    $endpoints = ''; // Link pagination does not support endpoints on pages 2 and up
                } else {
                    $last_page = true; // There's no next page, we're at the last page
                }
               } else {
                $last_page = true; // Couldn't find parameter link in headers, stop loop
            }
            if($no_pagination) {
                $last_page = true;
            }
        }
        $fp = fopen('checkouts.csv', 'w');
        // Loop through file pointer and a line
        foreach ($data as $fields) {
            fputcsv($fp, $fields,',');
        }
        fclose($fp);

        $fp = fopen('checkouts_lines.csv', 'w');
        // Loop through file pointer and a line
        foreach ($data2 as $fields) {
            fputcsv($fp, $fields,',');
        }
        fclose($fp);
    }