Cycling Through All Pages

What is the best way to cycle through pages until you reach the end of the data in the data base. Let’s assume we have a page size of five with 21 objects in the data base. Technically, this would produce five pages of data.

I know how to query the data base and I can move to the next page. I am not sure there is a way to move from the current page to the next one with a loop structure. Are there any thoughts on how to do this?

Hi Jon,
Let’s assume you use Anrdoid/Java SDK.
BackendlessCollections already provides you useful API for iterating over whole table.
Example pseudo-code will be like that:

BackendlessDataQuery dataQuery = new BackendlessDataQuery();
QueryOptions queryOptions = new QueryOptions();
queryOptions.setPageSize( 25 );
queryOptions.setOffset( 50 );
dataQuery.setQueryOptions( queryOptions );
BackendlessCollection c = Backendless.Data.of( “Person” ).find( dataQuery );
while (!c.getData().isEmpty()){
//do job here
c = c.nextPage();
}

Sorry for the delay. Thank you for the answer. One question when using this concept with Swift.

I am getting a warning when using the following line of code. “Expression of type “BackendlessCollection?” is unused”

result?.nextPage()

The full code block is below.

while !(result?.data!.isEmpty)!
            {
                print("Is this printing?")
                let currentData = result?.data as! [FollowBE]
                
                for follow in currentData
                {
                    print(follow.follower! as String)
                    print(follow.following! as String)
                }


                result?.nextPage()
            }

you get this warning because result?.nextPage() returns BackendlessCollection, but you do not use it
I am not sure if it works, but try next code


while !(result?.data!.isEmpty)!
{
print("Is this printing?")
let currentData = result?.data as! [FollowBE]
for follow in currentData
{
print(follow.follower! as String)
print(follow.following! as String)
}
result = result?.nextPage()
}  

In Swift this is not allowed. The code above produces an error stating that result is defined as let i.e. a constant.

You should define result as var

If I try this I am told that parameters are not allowed to be specified as vars.

Hi Jon,
This is obvious, you can not use vars in lambdas. You can move it to external field, or perform paging through external field stroring pageSize and offset.
Artur

Hi Jon,

You could use this approach with async fetching:

func basicPagingAsync() {
let startTime = Date()
let query = BackendlessDataQuery()
self.backendless?.persistenceService.of(Restaurant.self).find(
query,
response: { ( restaurants : BackendlessCollection?) -> () in
print("Total restaurants in the Backendless storage - \(restaurants!.totalObjects)")
self.nextPageAsync(restaurants!, startTime:startTime)
},
error: { ( fault : Fault?) -> () in
print("Server reported an error: \(fault!)")
}
)
}
func nextPageAsync(_ restaurants: BackendlessCollection, startTime: Date) {
let size = restaurants.getCurrentPage().count
if size == 0 {
print("Total time (ms) - \(1000*Date().timeIntervalSince(startTime))")
return
}
print("Loaded \(size) restaurant in the current page")
let currentPage = restaurants.getCurrentPage() as! [Restaurant]
for restaurant in currentPage {
if restaurant.name != nil {
print(restaurant.name!)
}
}
restaurants.nextPageAsync(
{ ( rests : BackendlessCollection?) -> () in
self.nextPageAsync(rests!, startTime:startTime)
},
error: { ( fault : Fault?) -> () in
print("Server reported an error: \(fault!)")
}
)

Thanks Vyacheslav

Maybe I looking at this the wrong way but it seems rather difficult to cycle through pages to get data from objects. If an async method is required then that means we have to use delegation to accomplish the task. While I can program this, it just seems like a lot of overhead for the task at hand. Am I missing something?

Here is an example with sync call:

func basicPaging() {
Types.tryblock({ () -> Void in
let startTime = Date()
let query = BackendlessDataQuery()
var restaurants = self.backendless?.persistenceService.of(Restaurant.self).find(query)
print("Total restaurants in the Backendless starage - \(restaurants?.totalObjects)")
var size = restaurants?.getCurrentPage().count
while size! > 0 {
print("Loaded \(size) restaurant in the current page")
restaurants = restaurants?.nextPage()
size = restaurants?.getCurrentPage().count
}
print("Total time (ms) - \(1000*Date().timeIntervalSince(startTime))")
},
catchblock: { (exception) -> Void in
print("Server reported an error: \(exception as! Fault)")
}
)
}

This is exactly what I was looking for. Thank you very much. This makes sense since we can declare restaurants as a var. Thanks again.