Forum Discussion

Paull's avatar
Paull
Frequent Visitor
9 years ago
Solved

Rest API _ Json _ several pages _ automatically call the next_page_URL

Hi Everyone,

I am a newbie on powerBi and would need your help to figure out how to automate a rest-API call with a Json response having several pages.
The initial URL is the following:
https://api.higring.com/v2/reporting/get?period=custom_date&start_date=2017-01-01&end_date=2017-07-20&data_type=adnetwork &group_by=date,platform,custom_1,custom_2, type,ad_format,connection,country&filter[]=network:network1

I get the following response:

The idea would be to automatically call the “next_page_url” until there is no “next_page_url”.
Any thoughts on how I can process this ?

Thanks a lot

  • Hi ImkeF,

     

    Thanks a lot for your reply. It helps a lot.
    I generate a script that do pretty much the same than the video. 
    It looks like this:

    let
     Source = Json.Document(Web.Contents(url, [Headers=[Authorization="your token"]])),
     iterations = Source[total_pages],          // get the information within the response
     url = "you URL", // here goes your URL
     
     FnGetOnePage =
      (url) as record =>
       let
        Source = Json.Document(Web.Contents(url, [Headers=[Authorization="yourtoken"]])),
        data = try Source[connections] otherwise null, //get the data of the first page
        next = try Source[next_page_url] otherwise null, // the script ask if there is another page
        res = [Data=data, Next=next]
       in
        res,
     
     GeneratedList =
      List.Generate(
       ()=>[i=0, res = FnGetOnePage(url)],
       each [i]<iterations and [res][Data]<>null,
       each [i=[i]+1, res = FnGetOnePage([res][Next])],
       each [res][Data]),
      #"Converti en table" = Table.FromList(GeneratedList, Splitter.SplitByNothing(), null, null, ExtraValues.Error)
    in
      #"Converti en table"

    It works perfectly.

    Have a good day,

     

    Paul

47 Replies

    • Paull's avatar
      Paull
      Frequent Visitor

      Hi ImkeF,

       

      Thanks a lot for your reply. It helps a lot.
      I generate a script that do pretty much the same than the video. 
      It looks like this:

      let
       Source = Json.Document(Web.Contents(url, [Headers=[Authorization="your token"]])),
       iterations = Source[total_pages],          // get the information within the response
       url = "you URL", // here goes your URL
       
       FnGetOnePage =
        (url) as record =>
         let
          Source = Json.Document(Web.Contents(url, [Headers=[Authorization="yourtoken"]])),
          data = try Source[connections] otherwise null, //get the data of the first page
          next = try Source[next_page_url] otherwise null, // the script ask if there is another page
          res = [Data=data, Next=next]
         in
          res,
       
       GeneratedList =
        List.Generate(
         ()=>[i=0, res = FnGetOnePage(url)],
         each [i]<iterations and [res][Data]<>null,
         each [i=[i]+1, res = FnGetOnePage([res][Next])],
         each [res][Data]),
        #"Converti en table" = Table.FromList(GeneratedList, Splitter.SplitByNothing(), null, null, ExtraValues.Error)
      in
        #"Converti en table"

      It works perfectly.

      Have a good day,

       

      Paul

      • markholland's avatar
        markholland
        Icon for Helper I rankHelper I

        Hi,

         

        I'm having real difficulties following the steps in this post with my API. I've watched the video, which differs from the code given at the bottom of this post. Neither approach has worked for me. I'll go through what I've done and hopefully someone can help me:

         

        Following the video I've added the following code:

         

        GetData

         

        (page as number) as table =>
        let
            Source = Json.Document(Web.Contents("https://api.harvestapp.com/v2/time_entries?access_token=********&account_id=********&page=" & Number.ToText(page))),
            Data1 = Source{1}[Data],
            RemoveBottom = Table.RemoveLastN(Data1,3)
        in
            RemoveBottom

         

        I've then copied the code to create the list of pages:

         

        let
            Source = List.Generate( () =>
          [Result = try GetData(1) otherwise null, Page = 1],
          each [Result] <> null,
          each [Result = try GetData([Page]+1) otherwise null, Page = [Page]+1],
          each [Result])
        in
            Source

         

        But when I do this I get nothing, just a column header with List but no list of pages.

         

        When I try the amended version in this post I get nothing either. Here's the code I'm using:

         

        let
         Source = Json.Document(Web.Contents(url, [Headers=[Authorization="********"]])),
         iterations = Source[total_pages],          // get the information within the response
         url = "https://api.harvestapp.com/v2/time_entries?access_token=********&account_id=********", // here goes your URL
         
         FnGetOnePage =
          (url) as record =>
           let
            Source = Json.Document(Web.Contents(url, [Headers=[Authorization="********"]])),
            data = try Source[connections] otherwise null, //get the data of the first page
            next = try Source[next_page_url] otherwise null, // the script ask if there is another page
            res = [Data=data, Next=next]
           in
            res,
         
         GeneratedList =
          List.Generate(
           ()=>[i=0, res = FnGetOnePage(url)],
           each [i]<iterations and [res][Data]<>null,
           each [i=[i]+1, res = FnGetOnePage([res][Next])],
           each [res][Data]),
            #"Converted to Table" = Table.FromList(GeneratedList, Splitter.SplitByNothing(), null, null, ExtraValues.Error)
        in
            #"Converted to Table"

        I really have no idea where I'm going wrong. Can anyone help? Paull ImkeF

         

         

        Thanks,

        Mark

  • TerriblyVexed's avatar
    TerriblyVexed
    Frequent Visitor

    Thank you all so much for this!!!

    One point of clarification - The GeneratedList had a typo in it about half way through the discussion.

    each [res][Next] <> null

    as the evaluator function should be

    each [res][Data] <> null

    it was this way in several posts and then got switched.

     

    I would like to share my version for anyone struggling with Fhir data.

    let 
        baseUrl = "https://{myurl}.azurewebsites.net",
        resource = "/Questionnaire",
        search = "?&_total=accurate",
        fullUrl = baseUrl & resource & search,
    
        // define the function
        FnGetOnePage =
            (url) as record =>
            let
                Source = Json.Document(Web.Contents(url)),
                data = try Source[entry] otherwise null,
                // link is list of records
                link = try Source[link] otherwise null,
                // link{0} could be "self", "next"
                next = if link{0}[relation] = "next"
                        then link{0}[url]
                        else null,
                res = [Data=data, Next=next]
            in
                res,
                
        // use the FnGetOnePage function with List.Generate    
        GeneratedList =
            List.Generate( ()=> 
                [result = FnGetOnePage(fullUrl)],
                // do while
                each [result][Data] <> null,
                // each row of list
                each [result = FnGetOnePage([result][Next])],
                // output
                each [result][Data]
                ),
        // convert to table from the output of function GeneratedList
        #"Converted to Table" = Table.FromList(GeneratedList, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
        #"Expand Table" = funcExpand(GeneratedList)
    in
        #"Expand Table"

    This uses not only the functions listed here but also the funcExpand function which auto expands all columns that have data.

     

    ImkeF  - thank you!

     

    Vexed

  • OK I have a similar issue trying to get this to work.

     

    I have an api which will only return 200 records but rather than the next url it gives me the lastid which I think I can tag onto the url to then give me the next page of results. So the simple code below return one page of data and not sure what the best way would be to go about doing this.

     

     

    let
    
         apiUrl = "myUrl",
    
         options = [Headers =[
    					#"Accept"="application/json",
    					#"Authorization"="myKey"]],
    
         result = Web.Contents(apiUrl , options),
        #"Imported JSON" = Json.Document(result,65001)
    in
        #"Imported JSON"

     

    The url would then look like this to search the next set and so on. I think thats how it would work anyway.

     

    https://myURL?after_id=1494

     

    The API says

    Pass the last id received, to receive records after it. Null can be passed to start at the beginning.

     

    Any help much appreiciated and I know this is an old thread but here goes.....

     

    Cheers

     

    Paul.

    • TerriblyVexed's avatar
      TerriblyVexed
      Frequent Visitor

      FPackermanGTA wrote:

      OK I have a similar issue trying to get this to work.

       

      I have an api which will only return 200 records but rather than the next url it gives me the lastid which I think I can tag onto the url to then give me the next page of results. So the simple code below return one page of data and not sure what the best way would be to go about doing this.

       

       

       

      let
      
           apiUrl = "myUrl",
      
           options = [Headers =[
      					#"Accept"="application/json",
      					#"Authorization"="myKey"]],
      
           result = Web.Contents(apiUrl , options),
          #"Imported JSON" = Json.Document(result,65001)
      in
          #"Imported JSON"

       

       

      The url would then look like this to search the next set and so on. I think thats how it would work anyway.

       

       

      https://myURL?after_id=1494

       

       

      The API says

      Pass the last id received, to receive records after it. Null can be passed to start at the beginning.

       

      Any help much appreiciated and I know this is an old thread but here goes.....

       

      Cheers

       

      Paul.


      And does it?

      • FPackermanGTA's avatar
        FPackermanGTA
        Icon for Advocate I rankAdvocate I

        Yes I just need a way to recursively enter the function with the previous 'last_id' appended to the base url until 'additional_pages' is False and then join it all together but struggling to do it. Any ideas?