get_it
get_it copied to clipboard
Flutter web (only in release or profile) TypeError: Cannot read properties of null (reading 'pendingResult')
I can run the app in android studio with no problem, when i run flutter run -d chrome --profile --dart-define=Dart2jsOptimization=O0 i get this error:

Have similar issue, which blocks my project running in production/profile
can you create a simple repro project, please?
@escamoteur Hi, I created a simple project that reproduces the same issue for me (HERE: https://github.com/HKop/getit-issue) It started happening once we extracted some of the files to a "lib_common" library and wanted to use them in the main app.
Project structure:
- getIt_issue main project.
- lib_common library in getIt_issue folder that has components used in the main project.
Note: Issue is only present on web in release or profile mode.
- To generate getIt files - "flutter packages pub run build_runner build --delete-conflicting-outputs" in the root getIt_issue folder;
- Then to run the app on web in profile mode - "flutter run --profile -d chrome --dart-define=Dart2jsOptimization=O0"
When opening the console, the following error is shown:
Otherwise, in debug mode, works properly and displays a button that calls a method from injected service:
P.S. The issue is not present also if the same classes are added to the main project (no lib_common present)
This looks very much like a compiler bug
OK, after looking a bit deeper into your provided project it really looks pretty odd what dart2js produces here
_i1.GetIt $initGetIt(_i1.GetIt get,
{String? environment, _i2.EnvironmentFilter? environmentFilter}) {
final gh = _i2.GetItHelper(get, environment, environmentFilter);
final libCommonModule = _$LibCommonModule(get);
gh.factory<_i3.ISecureStorage>(() => libCommonModule.webSecureStorage,
registerFor: {_web});
gh.factory<_i3.ISecureStorage>(() => libCommonModule.mobileSecureStorage,
registerFor: {_mobileOrDesktop});
gh.lazySingleton<_i3.AppSecureStorage>(
() => libCommonModule.appSecureStorage);
gh.singleton<_i4.ObjectManager>(libCommonModule.objectManager);
return get;
}
this is the dart code where it happens
the JS code for this part looks like
$initGetIt(get, environment) {
var t3, _null = null,
gh = A.GetItHelper$(get, environment, _null),
libCommonModule = new A._$LibCommonModule(get),
t1 = type$.String,
t2 = type$.ISecureStorage;
gh.factory$1$2$registerFor(new A.$initGetIt_closure(libCommonModule), A.LinkedHashSet_LinkedHashSet$_literal(["web"], t1), t2);
gh.factory$1$2$registerFor(new A.$initGetIt_closure0(libCommonModule), A.LinkedHashSet_LinkedHashSet$_literal(["mobileOrDesktop"], t1), t2);
if (gh._canRegister$1(_null))
gh.getIt.registerLazySingleton$1$3$dispose$instanceName(new A.$initGetIt_closure1(libCommonModule), _null, _null, type$.AppSecureStorage);
t1 = get.call$0();
if (gh._canRegister$1(_null)) {
t2 = A._setArrayType([], type$.JSArray_ObjectManager);
t3 = type$.void;
gh.getIt._register$3$6$disposeFunc$instance$instanceName$isAsync$shouldSignalReady$type(_null, new A.ObjectManager(t1), _null, false, type$.List_WillSignalReady._is(t2), B._ServiceFactoryType_1, type$.ObjectManager, t3, t3);
}
return get;
},
I have no idea were this line comes from
t1 = get.call$0();
also, the variable t1
isn't used anymore inside this function.
Looking at the code of call$0
it gets even weirder
call$1$0($T) {
var instance, _null = null,
instanceFactory = this._findFirstFactoryByNameAndTypeOrNull$1$2$type(_null, _null, $T),
t1 = instanceFactory.pendingResult;
if (t1 != null) {
t1 = instanceFactory.instance;
t1.toString;
instance = t1;
} else
instance = instanceFactory.getObject$2(0, _null, _null);
return $T._as(instance);
},
call$0() {
return this.call$1$0(type$.Object);
},
and I have no idea which part of my get_it package this should come from? My only hunch is could that be created from an assert
because the toString()
is really weird especially as the result isn't assigned to anything.
@kevmoo @leafpetersen
Several of my users are affected by this.
Flagging our web team on this now!
Thanks a lot
I'll follow up in more detail in the dart-sdk bug, but wanted to mention a couple things I noticed in my investigation:
- the .pendingResult or .toString are signal of a null-check failing
- the
t1 = call$0()
comes from inlining other code. In this case it is from thecall
method in theGetItImplementation
class. Which is invoked from this piece of generated code:
_i4.ObjectManager get objectManager =>
_i4.ObjectManager(_getIt<_i3.AppSecureStorage>());
- it's quite likely that dart2js has a bug related to
call
methods. If I change the generated code by hand to use_getIt.get<i3.AppSecureStorage>()
, then the code works for me locally.
Note that my experiments are with a trimmed-down version of the app, I haven't validated that this works again with the full application.
Thanks a lot for verifying that there is indeed a problem in dart2js. It would be pretty strange that it's a get_it code problem when 1000s of people use it on all other platforms Am 4. Feb. 2022, 22:04 +0100 schrieb sigmundch @.***>:
I'll follow up in more detail in the dart-sdk bug, but wanted to mention a couple things I noticed in my investigation:
• the .pendingResult or .toString are signal of a null-check failing • the t1 = call$0() comes from inlining other code. In this case it is from the call method in the GetItImplementation class. Which is invoked from this piece of generated code:
_i4.ObjectManager get objectManager => _i4.ObjectManager(_getIt<_i3.AppSecureStorage>());
• it's quite likely that dart2js has a bug related to call methods. If I change the generated code by hand to use _getIt.get<i3.AppSecureStorage>(), then the code works for me locally.
Note that my experiments are with a trimmed-down version of the app, I haven't validated that this works again with the full application. — Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you were mentioned.Message ID: @.***>
Any news on this? atm I can't compile my project to web. Maybe a temp fix?
Same error
Uncaught TypeError: Cannot read properties of null (reading 'toString')
at html_dart2js.dart:40810:45
at a6c.a (async_patch.dart:316:19)
at a6c.$2 (async_patch.dart:341:23)
at Object.ab (async_patch.dart:246:3)
at a6N (main.dart:10:27)
at js_helper.dart:2684:31
at js_helper.dart:2684:31
at dartProgram (js_helper.dart:2684:31)
at js_helper.dart:2684:31
Regarding the original issue here, note that we've continued the dart level discussion at https://github.com/dart-lang/sdk/issues/48304 - the specific issue with the get_it
package relates to using callable objects via the call
method.
@JHBitencourt - your error could potentially be caused by something else. toString
is the way dart2js represents null checks when emitting JavaScript, so this could be any kind of null check in a program. Usually those can be detected when running the application in debug mode. If not, I'd recommend trying first to isolate the issue in profile
mode (where dart2js generates almost identical code to release
mode but disables name minification).
@sigmundch thanks for replying. When in debug everything works perfect. Both profile and release mode produce the same output. I came here because at a6N (main.dart:10:27)
points to where I'm making a get_it
call. I'll investigate further though.
Any news on this? atm I can't compile my project to web. Maybe a temp fix?
Same error
Here (https://github.com/HKop/getit-issue) on another branch (called no-injectable) I managed to make it work, but it's not an ideal solution - in my case I tried registering dependencies manually in the lib_common package (without @injectable annotations). I still used @injectable in the main app with no problems. This resolved the issue for me, though I'd much prefer to use annotations with getIt instead of registering them manually.
There ara a related problem with flutter web, if you use getIt.registerSingleton<AppModel>(AppModelImplementation()); the error is NoSuchMethodError: method not found: 'pendingResult' on null but if use getIt.registerLazySingleton<RESTAPI>(() => RestAPIImplementation()); the error is NoSuchMethodError: method not found: 'db' on null
As a temporary solution i solved it by removing arguments from constructors of injected classes and I assigned every field with getIt().value
does this problem still exist? because a fix was added into the dart2js if I read the above link correctly?
To clarify - the fix landed in the Dart sdk and is part of the Dart 2.17 beta at the moment, it should be part of the 2.17 stable once that gets released. If flutter beta is in sync with Dart beta releases (which I believe it is), then I'd expect this to be resolved in both the master
and beta
flutter channels at the moment, but not on the stable channel.
can anyone confirm, that this is now solved?