Ravindra BagaleCourses & study guides मराठी Track your progress

5. Web Data, APIs and Google Sheets

5.3 Many Pages: Pagination with a Parameter and a Custom Function

Start with a problem

A partner API returns dark stores 2 per page. Ravina's query reads only page 1 and misses stores.

Explain simply

Build a query for one page, turn the page number into a parameter, convert the query into a function, then call the function for a list of page numbers and expand.

Show the data

Practice pages (JSON on this course site):

File Stores
web_darkstores_page_1.json S01 Kothrud (Pune), S02 Baner (Pune)
web_darkstores_page_2.json S03 Gangapur (Nashik), S04 College Road (Nashik)
web_darkstores_page_3.json S05 Rajarampuri (Kolhapur)

About this data: This table uses columns: File, Stores. This table uses columns: Page 1 query. This table uses columns: Page. Values shown are the lesson examples already on this page (not a new dataset).

Fictional sample data. Practice file: web_darkstores_page_1.json, web_darkstores_page_2.json, web_darkstores_page_3.json (source: src/practice/).

Demonstrate

  1. Copy the link of page 1. Create a Text parameter BaseUrl with everything before web_darkstores_page_1.json.
  2. Manage Parameters › New › PageNo, Decimal Number, current 1. Blank query: Json.Document(Web.Contents(BaseUrl, [RelativePath = "web_darkstores_page_" & Text.From(PageNo) & ".json"]))[stores] › To Table › expand.

    Your result should look like this:

    Page 1 query
    2 rows: S01, S02
  3. Right-click the query › Create Function… › fnGetStoresPage.

  4. New blank query = {1..3} › To Table › rename column Page › Whole Number.

    Your result should look like this:

    Page
    1, 2, 3
  5. Add Column › Invoke Custom Function › fnGetStoresPage, PageNo = Page › expand.

    Your result should look like this:

    storeId store city
    S01 Kothrud Pune
    S02 Baner Pune
    S03 Gangapur Nashik
    S04 College Road Nashik
    S05 Rajarampuri Kolhapur

Show the result

Your result should look like this (fictional sample):

Page Rows
1 2
2 2
3 1
Total 5

Explain what happened

The function wrapped the one-page logic; invoking it on the Page list ran it three times and stacked the results. The base URL stayed fixed and only RelativePath changed, which keeps Service refresh possible.

Explore further

  • Each page also returns pageCount (3). Use it to build the list: {1..Json.Document(...)[pageCount]} instead of hard-coding 3.

Detailed reference for this lesson:

Some sites or APIs show data page by page: …/stores?page=1, …/stores?page=2 … Build one query for a single page, turn it into a function, and call it for a list of page numbers.

Steps in Power BI

  1. Build a query for page 1 and clean it fully (for example a fictional partner site https://example.com/darkstores?page=1).
  2. Home › Manage Parameters › New Parameter › Name PageNo › Type Decimal Number › Current Value 1.
  3. Open Home › Advanced Editor and replace the hard-coded 1 in the URL with the parameter (see the code below).
  4. Right-click the query in the Queries pane › Create Function… › name it fnGetStoresPage. Power Query links the function to the query, so editing the query updates the function.
  5. Home › New Source › Blank Query and type = {1..5} (a list of pages) › To Table (List Tools › Transform) › rename the column to Page › set type to Whole Number.
  6. Add Column › Invoke Custom Function › Function query fnGetStoresPage › PageNo = column Page › OK.
  7. Click the expand icon on the new column to expand all columns. You now have all pages in one table.
// fnGetStoresPage
(PageNo as number) as table =>
let
    Source = Web.Contents("https://example.com",
                [RelativePath = "darkstores", Query = [page = Text.From(PageNo)]]),
    Page   = Html.Table(Text.FromBinary(Source), {{"Store", ".store-name"}, {"City", ".store-city"}},
                [RowSelector = ".store-card"])
in
    Page

Keep the base URL fixed for Service refresh

Write Web.Contents("https://example.com", [RelativePath = …, Query = […]]) instead of joining the whole URL as text ("https://example.com/darkstores?page=" & Text.From(PageNo)). The Power BI Service must be able to see the base URL to validate a dynamic data source. Otherwise scheduled refresh can fail with a message that the dataset contains dynamic data sources.

Practice task

Convert a one-page query into a function and load pages 1–3. Then make the last page number a parameter MaxPage and use {1..MaxPage}.

Ravindra Bagale's Tip

Friends, many students write a custom function for pagination but invoke it on hard-coded page numbers, so new pages never appear. Generate the page list dynamically (for example {1..PageCount}) and test with two or three pages first before loading everything. Add a small delay or limit the number of requests to respect the website. This matters for both exams and interviews.

Fix common mistakes

Wrong result Reason Correction
New page 4 never appears Page list hard-coded as Build the list from pageCount
Refresh fails in the Service: dynamic data source Whole URL built by joining text Static base URL + RelativePath
Function error on page 3 Expanded fields assumed 2 rows Expand by column names, not positions

Practise independently

Practice task

Count stores by city from the combined table.

Hints
  • 5 rows in total.
Solution

Pune 2, Nashik 2, Kolhapur 1.

Think like a professional

Respect API page sizes and rate limits; fetch only the pages you need and log the row count each refresh.

Ravi Sir's Cards for this lesson

मराठी cards