While overwriting in Server Action

Not sure if I’m doing something wrong or if this is a bug. I’m trying to get all photos from a Google album. Google serves a max of 100 photos at a time and provide a nextPage token to iterate through. I’m trying to use While to loop through while a nextpagetoken is provided.

What’s happening is the page loops through but only shows the last api_copy. I’ve confirmed this by changing the number of records returned by the API in each request using the pageSize parameter. The number of images returned in the api_copy is different. Those are also the last images in the album.

pageSize 50

pageSize 100

In my mind the api should be output in each iteration of the while but it appears it only outputs when it’s done. Is that by design?

Hi.
The while loop’s output is not the same as a repeat step. You will always just get the last iteration’s value outside the loop.
For the steps/data in the loop, you will have to do the processing inside the while loop itself.

That’s weird. I would have thought it would work the same way as a PHP or Javascript while. What’s the purpose of the while then and why is it different in Wappler?

For reference - PHP While - https://www.w3schools.com/php/phptryit.asp?filename=tryphp_loop_while and Javascript - https://www.w3schools.com/js/tryit.asp?filename=tryjs_while.

No, the purpose of while is exactly the same as in any other language. Its just different in terms of how output works as compared to a repeat step in Wappler.

@patrick
Is there a reason why the while step hasn’t got the option to output each iteration?

To get a result like this example, you could use:

image

Thanks Tom. Problem is I don’t know how many there will be.

This will output a list of all the values until the while condition is met. It isn’t dependent on knowing the number of loops. (Perhaps I’ve misunderstood the issue.)

Here is @patrick’s previous explanation:

Wouldn’t that only iterate 10 times? I might have 150 loops, I might have 1. If I knew how many loops I could just use repeat. Am I not understanding?

Oh - was that just an example? So maybe I could do

while {{next_page}}
API Action: api_copy
var api_full =. my_api + api_copy.data
Set Value next_page - {{api_copy.data.nextPageToken}}

That’s an idea although I’m not sure how to merge the arrays together.

Ah - ok. So it’s not doing what a normal While does. That’s a bummer but I’ll find a work around.

I have used a while loop in the past and written a custom formatter that combines the arrays that are received from a query/api call. I’ll see if I can find it

That would be great. Thx.

What server model are you using?

I’m using PHP

Here’s the custom formatter function:

function formatter_concatarr($arr1, $arr2){
    if(!is_array($arr1)){ $arr1 = array();} 
    if(!is_array($arr2)){ $arr2 = array();}
    $retval = array_merge($arr1,$arr2); 
return $retval; }

This is my server action file:

(note: each of the set values has a local and global name. It is the global one I will use)

I end up with one set of results (all pages of retrieved data) in an output value called items

Mine is not a Google call so you will need to adjust the pagination reference to the nextPageToken etc. but the sructure should get you closer to what you want

1 Like

Eventually we should make some kind of array store component also for server connect that you can use to init, add, append and output data in various steps. Maybe @patrick can check this.

1 Like

Thanks for this. Can’t seem to get it to work yet and Google just pinged me for going over my limit for the day so I’ll get back to it tomorrow. Just wanted to let you know I appreciate the help.

No problem. Happy to help.

Make sure for the Set Value steps you have a ‘Global Name’ set (I always make mine different to the local ‘Name’ property, just to be sure). Also make sure that when you use it later, you use the global name too. It won’t show in the picker so you have to type it by hand.

If you want to share your new API steps with me so I can have a look, please do.

Could we also have the option of adding a max iterations value to the while? (I can add it as a separate FR if required)

I can quickly think of two reasons it would be useful:

  • If you are expecting a change of data to break the loop and that doesn’t get set for some reason causing it to continue indefinitely
  • Testing (particularly 3rd party paginated API calls) without burning through a daily quota you might have