flutterflutter-isar

Build dynamic queries with Isar?


I am trying to be able to apply multiple sorts to a single list of Isar entities. I know Isar has the ability to apply multiple sorts through the .thenBy functions. Right now I have chips that allow the user to select multiple fields to sort by, and then whether they want it ascending or descending. From these selections we get an array of String's with the field to sort by, and a String containing either Ascending or Descending.

So if the selected fields are:
["name", "id", "location"]

and sort was set to
"Ascending"

I would want to build the query:
isar.entities.where().sortByNameAsc().thenById().thenByLocation()

My first thought was to just hard code every possible combination, but I really would prefer to not do that. Then I thought maybe I could have a Map<String, Function>, but I wasn't really sure how that could work.

I know this is a very niche feature, but I figured I would ask if it's even possible before ruling it out.

Also, a follow up question, using the example above, would sorting by more than one field even have an effect if their aren't multiples with the same name?


Solution

  • You can build dynamic queries by ignoring the protected_member rule. However, it's not recommended, dynamic queries are a lot more dangerous comparing to the generated code, and you need to make sure the input is valid field.

    Look at the generated code of thenByLocation()

    return QueryBuilder.apply(this, (query) {
          return query.addSortBy(r'location', Sort.asc);
        });
    

    so you can have something like this.

    final fields = ["name", "id", "location"];
    var currentQuery = collection.where();
    for (final field in fields) {
        // ignore: invalid_use_of_protected_member
        currentQuery = QueryBuilder.apply(currentQuery, (query) {
            return query.addSortBy(field, Sort.desc);
      });
    }
    currentQuery.findAll();