Get Version:
get: ^2.6.3
I'm trying to use the RXController with a simple list, based on readme 'snippet' (I may be trying to use it in a wrong way)
There are two issues:
The first one is that <T>[].obs on a list will not infer it's type (I'm not sure if you can add a parametric type on extensions, so this one can be easily solved with a cast)
The second one is that .value returns T, and not List<T>:
Minimal reproduce code
class FooItem {}
class FooController extends RxController {
static FooController get to => Get.find();
// final list = <FooItem>[].obs; // this is infered as ListX<dynamic>
final list = ListX<FooItem>(); // ok
void load() {
list.value = List<FooItem>(); // nop
}
}
class FooScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetX<FooController>(
init: FooController(),
builder: (_) {
// Edit: the issue is .value is infered as dynamic, so .value.length is not allowed
return ListView.builder(
itemCount: _.list.value.length, // Nop _.list.value is dynamic (AS shows it as FooItem)
padding: EdgeInsets.all(8.0),
itemBuilder: (context, index) {
final item = _.list.value[index]; // Nop, value is dynamic
return Text('Pls come to brazil!');
});
});
}
}
I see that the ListX is declared with
class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> {
But shouldn't it be declared with:
class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<List<E>> {
?
Or am I trying to use lists in a non intended way?
About RxInterface>, I really tried, right at the beginning, and faced problems with the add, remove, removeAt methods, which asked for a List
final _list = List<FooItem>().obs;
List<FooItem> get list => _list.value;
Lists are boring to work with, because it has reactivity not only in changing the object, but in each internal item, MobX for example, separated the lists into two List and ObservableList, and this approach is what I don't want to keep, that's why I inherited the list directly from Dart, for greater interoperability, but this is something that is still being studied for an even cleaner approach, and probably in the future it will have a better approach, but surely the approach mentioned above is safe, more stable (although another approach arises, it will remain safe) once you are accessing a declared object, and all operations of get, set, insert, add, or anything will explicitly go through the Flow (yes, you can do set operations also , and a separate explanation is worth it).
I don't think this is necessary, at least not in this example:
void load() {
list.value = List<FooItem>(); // nop
}
@jonataslaw
Thx for the explanation,
I don't think this is necessary, at least not in this example:
So I should be using
final _list = List<FooItem>().obs;
List<FooItem> get list => _list.value;
void load(){
_list
...clear()
...addAll(<FootItem>[]);
}
instead?
Just one more detail, this line:
List
get list => _list.value;
Gives an error, it needs a cast with strong mode enabled:
List<FooItem> get list => _list.value as List<FooItem>;
(the get signature is not needed, but I have an analysis rule that recommends it)
About RxInterface
, I really tried, right at the beginning, and faced problems with the add,
Could this be explored? (It's just an idea, didn't test it or anything, and it maybe show issues about T and R not being the same type)
abstract class RxInterface<T> extends Foo<T, T> {}
abstract class RxListInterface<T> extends Foo<List<T>, T> {}
abstract class NewRxInterface<T, R>{
// T for getter, R for other things
}
Anyway, thanks for the help!
Fix on 2.7.1, thanks for
Thanks for pointing that out. It was not possible to do something as you pointed out, but I was able to set the Value differently in ListX and now set and get operations should work normally, as long as list.value is used.