Describe the bug
It seems that calling Get.lazyPut() with a tag parameter throw an exception.
To Reproduce
Steps to reproduce the behavior:
Get.lazyPut() with this controller, assign a tag to itIsInit is called on nullExpected behavior
Everything should work normally...
Flutter Version:
1.20.0
Getx Version:
3.8.0
Describe on which device you found the bug:
Samsung SM A7000
Minimal reproduce code
class PageController extends GetxController {
String get text => "Example";
}
class PageBindings extends Bindings {
@override
void dependencies() => Get.lazyPut(() => PageController(), tag: "special-tag");
}
class Page extends GetView<PageController> {
@override
Widget build() => Container(child: Text(controller.text));
}
Possible solution
After a debugging session on the get code, I've found this line. The _lazyPuted_ dependency is not registered with the tag using Get.put() when calling Get.find() for the first time for that dependency. So the call to _initDependencies<S>(name: tag) will never find the right dependency.
I think changing this line to S _value = put<S>(_factory[key].builder() as S, tag: tag); will solve the issue...
@na2axl You can't use a GetView or GetWidget when you register your instance with a tag.
Those Widgets only makes use of the generic type <T>.
You can only use it with Get.find<Controller>(tag:"special-tag")...
tags are meant to give you the ability to use multiple different instances of the same type, that's why Get's dependency injection system, is not just a Singleton factory.
If you actually believe this is an issue, please create another one, and maybe we discuss another implementation with a function call (instead of a getter) like controller( tag: "something" ).
class PageController extends GetxController {
String get text => "Example";
}
class PageBindings extends Bindings {
@override
void dependencies() => Get.lazyPut(() => PageController(), tag: "special-tag");
}
class Page extends StatelessWidget {
PageController get controller => Get.find<PageController>(tag: "special-tag");
@override
Widget build() => Container(child: Text(controller.text));
}
Sorry @roipeker is my fault, I've just wanted to show a quick example, and I've used GetWidget as an _habit_. But no, this is not the reason of the problem. As I said, when you do Get.lazyPut(() => Controller(), tag: "tag"), the next call to Get.find(tag: "tag") will throw an exception saying The getter isInit was called on null. This is not beacause of GetWidget. And I think it is because of that:
S find<S>({String tag}) {
final key = _getKey(S, tag);
if (isRegistered<S>(tag: tag)) {
if (_singl[key] == null) {
if (tag == null) {
throw 'Class "$S" is not register';
} else {
throw 'Class "$S" with tag "$tag" is not register';
}
}
_initDependencies<S>(name: tag);
return _singl[key].getDependency() as S;
} else {
if (!_factory.containsKey(key)) {
// ignore: lines_longer_than_80_chars
throw '"$S" not found. You need to call "Get.put($S())" or "Get.lazyPut(()=>$S())"';
}
GetConfig.log('Lazy instance "$S" created');
var _value = put<S>(_factory[key].builder() as S); // THIS LINE HERE
_initDependencies<S>(name: tag);
if (GetConfig.smartManagement != SmartManagement.keepFactory &&
!_factory[key].fenix) {
_factory.remove(key);
}
return _value;
}
}
The dependency created using lazyPut with a tag is registered at the right time using put but without tag, so in _initDependencies:
bool _initDependencies<S>({String name}) {
final key = _getKey(S, name);
final isInit = _singl[key].isInit; // THIS LINE THROWS THE EXCEPTION
if (!isInit) {
_startController<S>(tag: name);
_singl[key].isInit = true;
if (GetConfig.smartManagement != SmartManagement.onlyBuilder) {
_registerRouteInstance<S>(tag: name);
}
}
return true;
}
The generated key doesn't match any dependency and the array access return a null value...
I'm reopening the issue, so please @roipeker or @jonataslaw investigate in this. Sorry for the last time I've not well explained the problem because I was a bit busy and I wanted to write something quickly.
This is a part of the stack trace:
โโโก EXCEPTION CAUGHT BY WIDGETS LIBRARY โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The following NoSuchMethodError was thrown building Builder(dirty):
The getter 'isInit' was called on null.
Receiver: null
Tried calling: isInit
The relevant error-causing widget was:
Navigator-[LabeledGlobalKey<NavigatorState>#a65be]
lib\โฆ\chat\chat_page.dart:111
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 GetInstance._initDependencies package:get/โฆ/instance/get_instance.dart:150
#2 GetInstance.find package:get/โฆ/instance/get_instance.dart:231
#3 Inst.find package:get/โฆ/instance/extension_instance.dart:54
#4 new ChatMessaging package:isintu_chat/โฆ/widgets/chat_messaging_widget.dart:46
#5 ChatPage.build.<anonymous closure>.<anonymous closure>.<anonymous closure> lib\โฆ\chat\chat_page.dart:126
#6 GetPageRoute.buildPage