Blog

How to Load Data Objects From the Server With Sorting

by on September 1, 2019

In another Recipe article, we discussed how to load data from the Backendless mbaas server using paging. In fact, data paging is only one of the features available in the data loading API. In this post, we are going to show how to fetch data objects with sorting. The sorting option can be combined with any other data loading feature. For example, you could have both sorting and the “where clause” in your data loading request. For this example, we are going to use the Restaurant-to-go app schema.


Here’s what my data in the Restaurant table looks like:

Consider the Restaurant class below. When our code fetches data from the server, it will arrive as a collection of the Restaurant class instances:

    import java.util.Date;
    
    public class Restaurant {
       public String cuisine;
       public String name;
       public Date created;
       public Date updated;
    }

    The class declares public fields, however, it could’ve been written as a Java bean (that is with public getters and setters). The Backendless SDK for Java/Android can work either one of the approaches.

    The code below loads the restaurant objects sorted in the ascending order by the “created” column/field. The ascending order is requested by the “ASC” qualifier.

    DataQueryBuilder dataQuery = DataQueryBuilder.create();
    dataQuery.addSortBy("created ASC");
    
    // fetch restaurants
    Backendless.Data.of(Restaurant.class).find(dataQuery, new AsyncCallback<List>() {
       @Override
       public void handleResponse(List restaurants) {
           for (Restaurant restaurant : restaurants) {
               Log.i(TAG, "Restaurant - " + restaurant.name + ", cuisine - " + restaurant.cuisine + ", created on " + restaurant.created);
           }
       }
    
       @Override
       public void handleFault(BackendlessFault fault) {
           Log.e(TAG, fault.getMessage());
       }
    });

    import java.util.Date
    
    data class Restaurant(var cuisine: String? = null, var name: String? = null,
       var created: Date? = null, var updated: Date? = null)

    The code below loads the restaurant objects sorted in the ascending order by the “created” column/field. The ascending order is requested by the “ASC” qualifier.

    val dataQuery = DataQueryBuilder.create()
    dataQuery.addSortBy("created ASC")
    
    // fetch restaurants
    Backendless.Data.of(Restaurant::class.java).find(dataQuery, object : AsyncCallback<List> {
       override fun handleResponse(restaurants: List) {
           for (restaurant in restaurants) {
               Log.i(TAG, "Restaurant - ${restaurant.name}, cuisine - ${restaurant.cuisine}, created on ${restaurant.created}")
           }
       }
    
       override fun handleFault(fault: BackendlessFault) {
           Log.e(TAG, fault.message)
       }
    })

    @interface Restaurant : NSObject
    
    @property(strong, nonatomic) NSString *cuisine;
    @property(strong, nonatomic) NSString *name;
    @property(strong, nonatomic) NSDate *created;
    
    @end

    The code below loads the restaurant objects sorted in the ascending order by the “created” column/field. The ascending order is requested by the “ASC” qualifier.

    DataQueryBuilder *queryBuilder = [DataQueryBuilder new];
    [queryBuilder setSortBySortBy:@[@"created ASC"]];
        
    [[Backendless.shared.data of:[Restaurant class]] findWithQueryBuilder:queryBuilder responseHandler:^(NSArray *restaurants) {
        for (Restaurant *restaurant in restaurants) {
            NSLog(@"Restaurant - %@, cuisine - %@, created on %@", restaurant.name, restaurant.cuisine, restaurant.created);
        }
    } errorHandler:^(Fault *fault) {
        NSLog(@"Error: %@", fault.message);
    }];

    @objcMembers class Restaurant: NSObject {
        var cuisine: String?
        var name: String?
        var created: Date?
    }

    The code below loads the restaurant objects sorted in the ascending order by the “created” column/field. The ascending order is requested by the “ASC” qualifier.

    let queryBuilder = DataQueryBuilder()
    queryBuilder.setSortBy(sortBy: ["created ASC"])
            
    Backendless.shared.data.of(Restaurant.self).find(queryBuilder: queryBuilder, responseHandler: { restaurants in
        if let restaurants = restaurants as? [Restaurant] {
            for restaurant in restaurants {
                print("Restaurant - \(restaurant.name ?? ""), cuisine - \(restaurant.cuisine ?? ""), created on \(restaurant.created)")
            }
        }
    }, errorHandler: { fault in
        print("Error: \(fault.message ?? "")")
    })

    const Backendless = require('backendless')
    /*
     Or use `import Backendless from 'backendless'` for client side.
     If you don't use npm or yarn to install modules, you can add the following line
     <script src="//api.backendless.com/sdk/js/latest/backendless.min.js"></script>
     to your index.html file and use the global Backendless variable.
    */
    
    Backendless.initApp('YOUR_APP_ID', 'YOUR_JS_API_KEY')
    
    const PAGE_SIZE = 100 // max possible value
    
    const fetchAllObjects = async tableName => {
      let offset = 0
      let totalCount = 0
      let lastPageSize = 0
      const itemsCollection = []
    
      do {
        const pageQuery = Backendless.DataQueryBuilder.create()
    
        pageQuery.setPageSize(PAGE_SIZE)
        pageQuery.setOffset(offset)
        pageQuery.setSortBy('created ASC')
    
        const items = await Backendless.Data.of(tableName).find(pageQuery)
    
        lastPageSize = items.length
    
        itemsCollection.push(...items)
    
        offset += PAGE_SIZE
        totalCount += lastPageSize
      } while (lastPageSize >= PAGE_SIZE)
    
      return itemsCollection
    }
    
    const onSuccess = restaurants => {
      restaurants.forEach(restaurant => {
        console.log('Restaurant - ' + restaurant.name + ', cuisine - ' + restaurant.cuisine + ', created on ' + new Date(restaurant.created))
      })
    }
    
    const onError = error => {
      console.error('Server reported an error: ', error.message)
      console.error('error code: ', error.code)
      console.error('http status: ', error.status)
    }
    
    Promise.resolve()
      .then(() => fetchAllObjects('Restaurant'))
      .then(onSuccess)
      .catch(onError)
    

    The code below loads the restaurant objects sorted in the ascending order by the “created” column/field. The ascending order is requested by the “ASC” qualifier.

    DataQueryBuilder dataQuery = DataQueryBuilder();
    dataQuery.sortBy = ["created ASC"];
    
    Backendless.Data.of("Restaurant").find(dataQuery).then((restaurants) {
      restaurants.forEach((restaurant) {
        print("Restaurant - ${restaurant['name']}, cuisine - ${restaurant['cuisine']}, created on ${restaurant['created']}");
      });
    });

    The code produces the following output – the objects are sorted by the “created” column:

    Restaurant - Endless Sweets, cuisine - bakery, created on Wed Jan 14 18:00:00 CST 2015
    Restaurant - McDonald's, cuisine - fastfood, created on Fri Jan 16 18:00:00 CST 2015
    Restaurant - Buca Di Bepo, cuisine - italian, created on Fri Jan 16 18:00:00 CST 2015
    Restaurant - Cantina Laredo, cuisine - mexican, created on Fri Jan 16 18:00:00 CST 2015
    Restaurant - Mister Cat, cuisine - pizzeria, created on Wed Feb 18 18:00:00 CST 2015
    Restaurant - Evraziya, cuisine - japanese, created on Wed Feb 18 18:00:00 CST 2015

    Enjoy!

    Leave a Reply