flutterdarthiveprisma-graphql

call hive in graphql


I would like to retrieve sessionToken and authToken from Hive, then put it inside GraphQLClient

main.dart

GetIt sl = GetIt.instance;

void main() async {
  // Register Service locator
  
  await initAuthServiceLocator(sl);
  ....
  await sl.allReady();
  runApp(...);
}

initAuthServiceLocator

Future<void> initAuthServiceLocator(
  GetIt sl, {
  isUnitTest = false,
}) async {
  if (!isUnitTest) {
    await Hive.initFlutter();
    ....
   sl.registerLazySingleton<Future<GraphQLClient>>(() => GraphQLClientGenerator().getClient());

  ....
}

GraphQLClientGenerator

  class GraphQLClientGenerator {
      GraphQLClientGenerator();
    
      Future<GraphQLClient> getClient() async {
        final authUserBox = await Hive.openLazyBox('authUserBox');
    
        var box = await authUserBox.getAt(0);
    
        debugPrint(box);
    
        final HttpLink httpLink = HttpLink(
            'https://xxx/graphqlmf?session_token="Get from box");
        final AuthLink authLink =
            AuthLink(getToken: () async => "Get from box");
        final Link link = authLink.concat(httpLink);
    
        return GraphQLClient(link: link, cache: GraphQLCache());
      }
    
    }

This is how I registered it

 sl.registerLazySingleton<Future<GraphQLClient>>(() => GraphQLClientGenerator().getClient());

Error

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building KeyedSubtree-[GlobalKey#1bbd2]:
Object/factory with  type GraphQLClient is not registered inside GetIt. 
(Did you accidentally do GetIt sl=GetIt.instance(); instead of GetIt sl=GetIt.instance;
Did you forget to register it?)
'package:get_it/get_it_impl.dart':
get_it_impl.dart:1
Failed assertion: line 372 pos 7: 'instanceFactory != null'

It seems like I can't add Future when register GraphQLClient. What is the correct approach if I want to call Hive in GraphQLClient since it requires async-await?


Edit

After I change to

sl.lazySingletonAsync<GraphQLClient>(GraphQLClientGenerator().getClient);

New error

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building KeyedSubtree-[GlobalKey#6665b]:
You tried to access an instance of GraphQLClient that is not ready yet
'package:get_it/get_it_impl.dart':
get_it_impl.dart:1
Failed assertion: line 404 pos 9: 'instanceFactory.isReady'

I have added await sl.allReady(); in main.dart, but still getting this issue.


Solution

  • Use @preResolve annotation from injectable library to solve this.

    Edited

    @module
    class GraphQLClientGenerator {
    
      @preResolve
      Future<GraphQLClient> getClient() async {
        final authUserBox = await Hive.openLazyBox('authUserBox');
    
        var box = await authUserBox.getAt(0);
    
        debugPrint(box);
    
        final HttpLink httpLink = HttpLink(
            'https://xxx/graphqlmf?session_token="Get from box");
        final AuthLink authLink =
            AuthLink(getToken: () async => "Get from box");
        final Link link = authLink.concat(httpLink);
    
        return GraphQLClient(link: link, cache: GraphQLCache());
      }
    
    }
    

    This works when you do build_runner to auto-generate the code.

    Or

    Use lazySingletonAsync by to solve this.

     sl.lazySingletonAsync<GraphQLClient>(() => GraphQLClientGenerator().getClient);