DirtyNative
DirtyNative

Reputation: 2834

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?

Upvotes: 6

Views: 6345

Answers (2)

Prawesh Panthi
Prawesh Panthi

Reputation: 348

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());

Upvotes: 3

Josh
Josh

Reputation: 1151

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);
          }
        });
  },
);

Upvotes: 9

Related Questions