Creating your own IterableEntity / Iterable2Entity kind

You can easily create your own IterableEntity / Iterable2Entity kind that holds any collection of your choice, as long as it can be converted to one/two iterables.

For example, let's create an IterableEntity which holds a two-dimensional list of modddels (A list of lists of modddels). Let's name it "MultiListEntity".

// 1.
@TypeTemplate('List<List<#1>>')
// 2
abstract class MultiListEntity<I extends InvalidEntity, V extends ValidEntity>
    extends IterableEntity<I, V> {
  // 3
  @protected
  @optionalTypeArgs
  List<List<R>> $primeCollection<R>(List<List<R>> collection) {
    final nestedLists = collection.map(List.unmodifiable);
    return List.unmodifiable(nestedLists);
  }

  // 4
  @protected
  @optionalTypeArgs
  Iterable<R> $collectionToIterable<R>(List<List<R>> collection) {
    return collection.expand((nestedList) => nestedList);
  }

  // 5
  @protected
  @optionalTypeArgs
  List<List<R>> $castCollection<S, R>(List<List<S>> source) {
    return source.map((nestedList) => nestedList.cast<R>()).toList();
  }

  // 6
  @override
  String $description(int index) => 'MultiList item $index';
}
  1. We specify the Type Template using the TypeTemplate annotation. Because we're making an IterableEntity, it must contain one mask only : "#1".

  2. We declare MultiListEntity as an abstract class that extends IterableEntity.

  3. We declare a method named $primeCollection : This is a method that modifies the collection each time an instance of the Modddel is created. It's mainly used when you have a dart collection that you want to make unmodifiable. Otherwise, you can just directly return the collection.

  4. We declare a method named $collectionToIterable : This method converts the collection to an iterable of R.

  5. We declare a method named $castCollection : This method casts the collection from holding S to holding R (from List<List<S>> to List<List<R>>).

  6. (Optional) You can also override $description.

The process of making an Iterable2Entity is pretty similar, with a few differences :

  1. The TypeTemplate must contain two masks : "#1" and "#2".

  2. You should extend Iterable2Entity instead of IterableEntity.

  3. $primeCollection works the same way

  4. $collectionToIterable returns a record where the first field is the first iterable (of R1), and the second field is the second iterable (of R2).

  5. $castCollection casts the collection from holding S1 and S2 to holding R1 and R2.

  6. (Optional) You can also override $description1 and $description2.

The methods $primeCollection, $collectionToIterable and $castCollection can have as many type arguments as needed so that the parameters and the return types are fully typed. You can check out the source code of MappedValuesEntity and MapEntity as examples.

For both IterableEntity and Iterable2Entity kinds, you should never override $validateContent.

Last updated