Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter GetIt throws instance exception

I am trying to register my services within my flutter application using get_it and one dependency needs to be initialized right at the start with an async call. As I have read on the official Get_It pub page, this should not be a problem, as long as I am defining the dependsOn property for dependencies which depends on that initializable class.

In my example, DeviceInfo is the class which needs to be initialized and Gateway and WorkingTimeRepository both depend on this class. Both have defined their dependOn property.

void setup() {
  getIt.registerSingletonAsync<DeviceInfo>(() async => DeviceInfo.init());

  getIt.registerSingletonWithDependencies(
      () => Gateway(deviceInfo: getIt.get()),
      dependsOn: [DeviceInfo]);

  getIt.registerSingletonWithDependencies<WorkingTimeRepository>(
      () => WorkingTimeRepository(
          dio: new Dio(), httpHeader: new HttpHeader(), gateway: getIt.get()),
      dependsOn: [DeviceInfo, Gateway]);
}

Now when my application starts and my first Widget wants to access the WorkingTimeRepository, I instantly get an exception:

════════ Exception caught by widgets library ═══════════════════════════════════ The following assertion was thrown building MainView: You tried to access an instance of WorkingTimeRepository that was not ready yet 'package:get_it/get_it_impl.dart': Failed assertion: line 322 pos 14: 'instanceFactory.isReady'

I cannot find my mistake I did, also I thought that when accessing the registered type, it resolves all dependent dependencies

Does someone know what is missing here?

like image 660
DirtyNative Avatar asked Sep 04 '26 21:09

DirtyNative


2 Answers

When using async dependencies, you need to wait until all dependencies are created before starting your app. One way to do this is adding a TransitionBuilder to the MaterialApp with a FutureBuilder that listens to getIt.allReady().

Example:

return MaterialApp(
  builder: (context, widget) {
    return FutureBuilder(
        future: getIt.allReady(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData) {
            return widget;
          } else {
            return Container(color: Colors.white);
          }
        });
  },
);
like image 141
Josh Avatar answered Sep 06 '26 23:09

Josh


ISSUE : You tried to access an instance of SharedPrefsService that is not ready yet.

If you are initializing any await or any function which takes time.Use

registerSingletonAsync

instead of

registerLazySingletonAsync

at top because if any other singleton is using that async instance it wont be ready and you will encounter that issue. For me it was because i used

locator.registerLazySingletonAsync<SharedPrefsService>(
      () async => SharedPrefsService.getInstance());
  
locator.registerLazySingleton<AuthLocal>(() => AuthLocalImpl());

and my authlocal class was using sharedprefService instance through di WHICH WAS WRONG !

My Final code was which SOLVED MY issue was

 locator.registerSingletonAsync<SharedPrefsService>(
      () async => SharedPrefsService.getInstance());

  locator.registerLazySingleton(() => AppRouter());
like image 30
Prawesh Panthi Avatar answered Sep 06 '26 21:09

Prawesh Panthi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!