Hey,
I’m trying to paginate results from a Notion API database, so that if the property has_more is true, it makes a second call (it can only handle 100 entries at a time).
the strange thing is Label3 is showing has_more to be true. But when I try to use the logic IF has_more is true, it seems to fail? I tried using the true/false logic blocks to no avail. Is the converted JSON value not a text string?
Thanks in advance.
JSON responses are always objects and when you use the get property of object
block with the get JSON from object
block, you should be getting a text string in return.
Can you post the full JSON response as text here (it’s easiest to assign the green response
block to a text input which allows you to then copy that response), using the </> button in the toolbar to format it to remove smart quotes? Or if not the full response, at least the section containing the “true” value?
Also, have you tried a simple debugging step of changing a label’s text when the if
condition is met? I would imagine the screen background color would be a good indication but I’d want to know if an even simpler change occurs based on the if
block.
Yes i tried a simple debugging step like change label to a text, no luck. It’s not recognising the IF true.
Here’s the same code from last time, it’s the same project i’m working on.
{
"object": "list",
"results": [{
"object": "page",
"id": "48c6396c-511d-4153-b21e-ae24e4539975",
"created_time": "2024-09-02T06:25:00.000Z",
"last_edited_time": "2024-09-02T06:27:00.000Z",
"created_by": {
"object": "user",
"id": "7b6aa778-199b-4934-ac6a-8836cddf4e56"
},
"last_edited_by": {
"object": "user",
"id": "7b6aa778-199b-4934-ac6a-8836cddf4e56"
},
"cover": null,
"icon": null,
"parent": {
"type": "database_id",
"database_id": "f984546d-7319-403d-a9c9-53e5f3095ee2"
},
"archived": false,
"in_trash": false,
"properties": {
"Photo": {
"id": "%3CAi%3E",
"type": "files",
"files": []
},
"Email Address": {
"id": "As%60t",
"type": "email",
"email": null
},
"Consent": {
"id": "Ay%7C%5D",
"type": "checkbox",
"checkbox": false
},
"⏰ Appointment Scheduler": {
"id": "B%7CpL",
"type": "relation",
"relation": [],
"has_more": false
},
"Phone Number": {
"id": "Ed%5Bd",
"type": "phone_number",
"phone_number": null
},
"Appt Status": {
"id": "LCkr",
"type": "rollup",
"rollup": {
"type": "array",
"array": [],
"function": "show_original"
}
},
"Tag": {
"id": "V%3FNa",
"type": "multi_select",
"multi_select": [{
"id": "efee7675-f920-4952-a6c2-c2c0f79fde5d",
"name": "Registrar",
"color": "yellow"
}]
},
"Person Type": {
"id": "XEUg",
"type": "multi_select",
"multi_select": [{
"id": "e9779d71-124b-47fb-bef4-7395bb8edf0f",
"name": "Doctor",
"color": "red"
}]
},
"Specialty ": {
"id": "%5Bnrd",
"type": "multi_select",
"multi_select": [{
"id": "TViY",
"name": "Psychiatry",
"color": "red"
}]
},
"RX Tier": {
"id": "%5CAci",
"type": "select",
"select": null
},
"Property": {
"id": "dgca",
"type": "rich_text",
"rich_text": [{
"type": "text",
"text": {
"content": "OOHC/WFT Ingleburn C&A",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "OOHC/WFT Ingleburn C&A",
"href": null
}]
},
"Next Appt": {
"id": "k_Rm",
"type": "rollup",
"rollup": {
"type": "array",
"array": [],
"function": "show_original"
}
},
"AM Tier": {
"id": "vBdZ",
"type": "select",
"select": null
},
"Last Seen": {
"id": "vq%7Bp",
"type": "date",
"date": {
"start": "2024-08-16",
"end": null,
"time_zone": null
}
},
"Primary Parent": {
"id": "v%7B%60%5E",
"type": "rich_text",
"rich_text": []
},
"Name": {
"id": "title",
"type": "title",
"title": [{
"type": "text",
"text": {
"content": "Donnet, Cameron",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "Donnet, Cameron",
"href": null
}]
}
},
"url": "https://www.notion.so/Donnet-Cameron-48c6396c511d4153b21eae24e4539975",
"public_url": null
}, {
"object": "page",
"id": "6161fdab-fb47-4f20-b9f4-c3f30d9ced17",
"created_time": "2024-09-02T06:23:00.000Z",
"last_edited_time": "2024-09-02T06:24:00.000Z",
"created_by": {
"object": "user",
"id": "7b6aa778-199b-4934-ac6a-8836cddf4e56"
},
"last_edited_by": {
"object": "user",
"id": "7b6aa778-199b-4934-ac6a-8836cddf4e56"
},
"cover": null,
"icon": null,
"parent": {
"type": "database_id",
"database_id": "f984546d-7319-403d-a9c9-53e5f3095ee2"
},
"archived": false,
"in_trash": false,
"properties": {
"Photo": {
"id": "%3CAi%3E",
"type": "files",
"files": []
},
"Email Address": {
"id": "As%60t",
"type": "email",
"email": null
},
"Consent": {
"id": "Ay%7C%5D",
"type": "checkbox",
"checkbox": false
},
"⏰ Appointment Scheduler": {
"id": "B%7CpL",
"type": "relation",
"relation": [],
"has_more": false
},
"Phone Number": {
"id": "Ed%5Bd",
"type": "phone_number",
"phone_number": null
},
"Appt Status": {
"id": "LCkr",
"type": "rollup",
"rollup": {
"type": "array",
"array": [],
"function": "show_original"
}
},
"Tag": {
"id": "V%3FNa",
"type": "multi_select",
"multi_select": [{
"id": "efee7675-f920-4952-a6c2-c2c0f79fde5d",
"name": "Registrar",
"color": "yellow"
}]
},
"Person Type": {
"id": "XEUg",
"type": "multi_select",
"multi_select": [{
"id": "e9779d71-124b-47fb-bef4-7395bb8edf0f",
"name": "Doctor",
"color": "red"
}]
},
"Specialty ": {
"id": "%5Bnrd",
"type": "multi_select",
"multi_select": [{
"id": "TViY",
"name": "Psychiatry",
"color": "red"
}]
},
"RX Tier": {
"id": "%5CAci",
"type": "select",
"select": null
},
"Property": {
"id": "dgca",
"type": "rich_text",
"rich_text": [{
"type": "mention",
"mention": {
"type": "page",
"page": {
"id": "3ccc4bd1-7285-438a-a847-a6bda3b2d40b"
}
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "Campbelltown Hospital",
"href": "https://www.notion.so/3ccc4bd17285438aa847a6bda3b2d40b"
}, {
"type": "text",
"text": {
"content": " ",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": " ",
"href": null
}]
},
"Next Appt": {
"id": "k_Rm",
"type": "rollup",
"rollup": {
"type": "array",
"array": [],
"function": "show_original"
}
},
"AM Tier": {
"id": "vBdZ",
"type": "select",
"select": null
},
"Last Seen": {
"id": "vq%7Bp",
"type": "date",
"date": {
"start": "2024-08-16",
"end": null,
"time_zone": null
}
},
"Primary Parent": {
"id": "v%7B%60%5E",
"type": "rich_text",
"rich_text": []
},
"Name": {
"id": "title",
"type": "title",
"title": [{
"type": "text",
"text": {
"content": "Islam, Nabilah",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "Islam, Nabilah",
"href": null
}]
}
},
"url": "https://www.notion.so/Islam-Nabilah-6161fdabfb474f20b9f4c3f30d9ced17",
"public_url": null
}],
"next_cursor": "7ef3586e-a4d5-4971-a344-260405847718",
"has_more": true,
"type": "page_or_database",
"page_or_database": {},
"request_id": "bd9ad48c-4bc0-469c-acbe-d0d578295bca"
}
I’m really stuck,
Thanks in advance
I think I see the problem:
The JSON you’re getting has a value of false for the “has_more” property. Not a value of “false” (a text string) but rather a value of false (a boolean). Since there are no quotes around it, it’s not a text string.
So when you compare that property, you have to compare it to a boolean. You can use the true
boolean blocks in Thunkable or you can just say if
[property] do… because the default for an if
block is to do something if the value after the if
is true.
Thanks for that.
The one you’re looking at is “results[1].properties[“ Appointment Scheduler”].has_more”. The property I’m referring to is “has_more” at the bottom of the page, which has value true.
Thanks for clarifying that the JSON value is in boolean and not text string. However, even when trying the boolean variable in thunkable, it doesn’t seem to be working.
Is this how it should be set up?
Or this?
both configurations have not worked.
The only other workaround i can think of is using the next_cursor property, as it is what is used to navigate to the next part of the database. so usually if has_more is false, then next_cursor is empty.
Yes, those were the block combinations I was suggesting.
If that’s not working then there’s another cause for the issue you’re having.
If I take your JSON text and use it in a Thunkable project, I can parse the [object] → “has_more” property and it returns a value of true. These blocks display “boolean” when I preview it:
I also checked without the boolean test and it’s not returning a text string. It’s definitely a boolean.
I figured out the debug test wasn’t working due to some sketchy logic further down (repeat nested in IF/DO) . When i stripped all that way, the debug test using boolean values worked.
I was trying to create a loop where it can keep calling the API until all data is loaded, but I think there might be an issue with having an api call nested in another api call. I ended up settling for a less than optimal solution of doing the first API call, copying the values to the local database, wait a few seconds, and do the next API call. It’s not automated, and as the database will grow I will have to manually add the next API call.
Thanks for the help!
You’re welcome! I’m glad to hear you made some progress. You might ask ChatGPT or Microsoft Copilot how to best handle that. If nesting doesn’t work, why not just call the API in parallel? Make a bunch of calls at the same time or one right after another. I don’t see any reason why you have to wait for one call to finish before making the next. Or use a loop rather than nesting if that’s possible for what you’re trying to do. You might need a slight pause (e.g. wait 0.03 seconds or just wait 0 seconds sometimes works) in the loop to allow the next call to start.
The reason i would need to wait between API calls is that i need to extract the next_cursor property from the first call, which is then used to retrieve the next page of results.
This is how I got it working for anyone that might find it useful:
I was able to make the loop work!
The trick was to set the repeat function WHILE has_more = True
before I was attempting to set the repeat UNTIL has_more= False - which did not work.
Not sure why that made the difference, but it works.
The WAIT functions seem necessary as it seems to average 1.5sec per call. I set it to 2.5sec just to be safe.