Getx: Worker is not disposed with controller

Created on 20 Jul 2020  路  3Comments  路  Source: jonataslaw/getx

i'm trying to stream the device position in a controller and listem to it in some page, each page can handle this change diferently, But when i leave the page and the page controller is disposed it's worker keep listening and when i enter the page again another worker is created keeping the two. i'm doing something wrong or this is the expected behavio?

the place where i'm streaming

class LocationService extends GetxController {
  static LocationService get to => Get.find();

  final position = Rx<Position>();

  @override
  void onInit() {
    super.onInit();

    Geolocator().getPositionStream().listen((event) {
      print('geolocator atualizou a posi莽ao');
      position(event);
    });
  }
}

how i'm listening to it

@override
  void onInit() {
    super.onInit();

    ever(LocationService.to.position, (_) {
      print('ever executado: $_');
    });
  }

Most helpful comment

Update to last version and:

final position = Rx<Position>();
Worker _ever;

onInit(){
_ever = ever(position, (_) { // it's is local
   print('ever executado: $_');
});

onClose(){
_ever.dispose();
}

All 3 comments

Do you see that the controller was discarded in the LOG? If you see, the controller has been dropped.
From what I understand from the code, you are attaching a listener to 'LocationService.position'.
You are not creating a local listener, you are listening to a listener from another page, so he will never be discarded.

final position = Rx<Position>();

ever(position, (_) { // it's is local
   print('ever executado: $_');
});
ever(LocationService.to.position, (_) { // This is to attach a listener to an observable from another page.
   print('ever executado: $_');
});

If you want to create a new listener and discard it, you can create a local variable, and use variable.bindStream (Class.to.otherRx.stream).

But the way you are doing it, you are attaching an ever to your main controller, and until it is deleted, that ever will work.

You can also use conditions in an ever, like
ever(variable, (_) {}, condition: Get.currentPage == '/home');

Using the current page condition leads to another problem: is created a new work every time i enter the page, so the callback will be executed multiple times.

I try the using the binding stream, but get a exception when leave the page

  final position = Rx<Position>();

  @override
  void onInit() {
    super.onInit();

    position.bindStream(LocationService.to.position.stream);
  }

  @override
  void onClose() {
    position.close();
    super.onClose();
  }

[ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Bad state: Cannot add new events after calling close
E/flutter (30636): #0 _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:249:24)
E/flutter (30636): #1 _RxImpl.value= (package:get/src/rx/rx_impl.dart:59:13)
E/flutter (30636): #2 _RxImpl.bindStream. (package:get/src/rx/rx_impl.dart:68:62)
E/flutter (30636): #3 _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter (30636): #4 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter (30636): #5 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter (30636): #6 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11)
E/flutter (30636): #7 _DelayedData.perform (dart:async/stream_impl.dart:611:14)
E/flutter (30636): #8 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:730:11)
E/flutter (30636): #9 _PendingEvents.schedule. (dart:async/stream_impl.dart:687:7)
E/flutter (30636): #10 _rootRun (dart:async/zone.dart:1182:47)
E/flutter (30636): #11 _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (30636): #12 _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter (30636): #13 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1037:23)
E/flutter (30636): #14 _rootRun (dart:async/zone.dart:1190:13)
E/flutter (30636): #15 _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (30636): #16 _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter (30636): #17 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1037:23)
E/flutter (30636): #18 _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/flutter (30636): #19 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)

Update to last version and:

final position = Rx<Position>();
Worker _ever;

onInit(){
_ever = ever(position, (_) { // it's is local
   print('ever executado: $_');
});

onClose(){
_ever.dispose();
}
Was this page helpful?
0 / 5 - 0 ratings