What you’re asking won’t be possible.
Even if you create the code in a separate lib in pure Dart, this lib will have to be compiled in the Flutter project. The runtimes Dart script and Flutter are different, one is converted to Javascript and runs on Nodejs, and the other is converted to code native to Android or iPhone, as a result there are some features that are unique to certain runtimes, and the reflect
is one of them.
What you can do will give you more work, but it’s something you’ve already expected from Dart projects: create the methods toJSON
in their classes to turn them into a Map<String, dynamic>
, such a method is a standard used to convert your objects into a string in format JSON.
Example
Here I will take advantage to declare an abstract class with this method to be able to use this contract later:
abstract class JsonSerializable {
Map<String, dynamic> toJSON();
}
class User implements JsonSerializable {
String name;
String email;
User({ required this.name, required this.email });
@override
Map<String, dynamic> toJSON() {
return {'name': name, 'email': email};
}
}
Having this method implemented, we can convert the object into an instance of Map
and access properties from a string.
I’m gonna use a Generic function to make typing safe:
List<T> filterElementsInList<T extends JsonSerializable>({
required String query,
required String elementAttribute,
required List<T> list,
}) {
if (query.isEmpty) return list;
return list.where((entity) => entity.toJSON()[elementAttribute].contains(query)).toList();
}
The use is as you already expect:
final users = [
User(name: 'Darcey', email: '[email protected]'),
User(name: 'Gisella', email: '[email protected]'),
User(name: 'Eliot', email: '[email protected]'),
User(name: 'Montgomery', email: '[email protected]'),
User(name: 'Drucill', email: '[email protected]'),
];
final filtered = filterElementsInList(query: 'Eliot', elementAttribute: 'name', list: users);
print(filtered[0].email);
But the implementation in Dart?
reflect
allows you to dynamically access the properties of an object without having to manually implement auxiliary methods. But this approach requires understanding the abstractions that language applies in its code, and it’s easy to fall into edge case. Read more on mirrors.
Example
List<T> filterElementsInList<T extends Object>({
required String query,
required String elementAttribute,
required List<T> list,
}) {
if (query.isEmpty) return list;
return list.where((entity) => reflect(entity).getField(Symbol(elementAttribute)).reflectee.contains(query)).toList();
}
I don’t understand exactly what you’re trying to do. Your question is how to use a string (like
elementAttribute
in your example) to access a property dynamically, that’s it?– Andre
Exact. Imagine the value passed to the parameter
elementAttribute
isname
. This would be the property actually sought in the element.– GILBERTO OLIVEIRA
As far as I understand, it is possible to do this using
reflect
in Dart, but the same is not possible in Flutter (I imagine it is for this purpose that you are using). Please describe the situation further, depending on the case you may usereflect
, or you will have to implement an interfaceToMap
objects that will be used in this function, or perhaps it is not necessary/feasible to do so.– Andre
It will be used in a Flutter application, however I am putting this code in a separate library
package
pure Dart. This is the reason why you want to receive the property as a parameter and access it dynamically in the object since I do not know beforehand what parameters the object/element of the list will have.– GILBERTO OLIVEIRA