Reputation: 3489
I am using the following package https://pub.dev/packages/get .
I have the following controller
class GroupController extends GetController{
StreamController<GroupModel> _streamController = BehaviorSubject();
Stream<GroupModel> get stream => _streamController.stream;
GroupController(DatabaseService database, GroupModel group)
{
_streamController.addStream(database.groupStream(group));
}
@override
void dispose(){
print('dispose');
_streamController.close();
super.dispose();
}
}
But when I call it the dispose is never called. I call it like this
GetBuilder<GroupController>(
init: GroupController(database, _group),
builder: (GroupController groupController) => StreamBuilder(
stream: groupController.stream,
builder: (BuildContext context, AsyncSnapshot<GroupModel> groupSnapshot) {
I want my controller's dispose method being called whenever the controller is removed from memory.
I noticed that the GetBuilder has a dispose callback. And it requires the state from a widget. So do I need to make the widget that holds the controller statefull? Or do I need to pass a new statefull widget that holds the state? The documentation is not all to clear on it. How do I call the dispose on my controller?
I noticed there is a console log whenever a controller get's deleted from memory, isn't there a callback so I can close the stream there? I would really like to avoid making the widget statefull tho.
Edit
class GroupController extends GetController{
StreamController<GroupModel> _streamController = BehaviorSubject();
Stream<GroupModel> get stream => _streamController.stream;
GroupController(DatabaseService database, GroupModel group)
{
_streamController.addStream(database.groupStream(group));
}
@override
void close(){
print('log if close is invoked');
_streamController.close();
super.close();
}
}
Generate the following log
I/flutter (23404): log if close is invoked
I/flutter (23404): Close can't be called
I/flutter (23404): [GET] GroupController deleted from memory
Somehow it error when trying to close the controller
Upvotes: 4
Views: 8090
Reputation: 2227
If you insert a 'dispose' into your GetController, it will be ignored. This is because disposing is a method for discarding widgets in a StatefulWidget class, not for discarding controllers, not least because Get automatically and intelligently discards controllers to free resources when it is no longer needed. If you want to close streams, Get does it automatically, as long as you insert your streams into the onClose method.
class GroupController extends GetxController {
StreamController<GroupModel> _streamController = BehaviorSubject();
Stream<GroupModel> get stream => _streamController.stream;
GroupController(DatabaseService database, GroupModel group);
@override
void onInit() {
_streamController.addStream(database.groupStream(group));
super.onInit();
}
// this
@override
void onClose() {
print('dispose');
_streamController.close();
super.onClose();
}
}
If you are using an old version of Get, you can use the same close and close method manually:
GetBuilder<GroupController>(
init: GroupController(database, _group),
builder: (GroupController groupController) => StreamBuilder(
stream: groupController.stream,
builder: (BuildContext context, AsyncSnapshot<GroupModel> groupSnapshot) {
Upvotes: 6
Reputation: 3489
This is probably how you want to be doing it. Not adding the stream in the contructor because this causes problems when the controller get's rebuild. Because it will add the stream to the contructor once more.
import 'dart:async';
import 'package:get/get.dart';
import 'package:rxdart/rxdart.dart';
class GetStreamController<T> extends GetController {
final Stream<T> Function() value;
StreamController<T> _streamController = BehaviorSubject();
StreamSubscription _streamSubscription;
Stream<T> get stream => _streamController.stream;
GetStreamController(this.value);
@override
void onInit()
{
super.onInit();
_streamSubscription = value().listen((event) {
_streamController.add(event);
});
}
@override
void onClose()
{
super.onClose();
_streamSubscription.cancel();
_streamController.close();
}
}
Upvotes: 1