Search code examples
flutterinitializerflutter-hiveflutter-cubitflutter-isar

Passing a constructor initialized value to another method


I want to use the local db "isar" in flutter together with cubit state management. In the following code:

  1. The variable "isarIn" is initialized in the main() method
  2. Then passed to MainApp class
  3. And then shall be again forwarded when creating a repository object "localIsarRepository"

I get an error message "The instance member '_isarIn' can't be accessed in an initializer. Try replacing the reference to the instance member with a different expression" Of course I checked the solutions provided, but they don't fit.

Can anyone help please?

void main() async {

  final dir = await getApplicationDocumentsDirectory();


  final isarOut = await Isar.open(
    [CostSchema],
    directory: dir.path,
  );

  runApp(MainApp(isarIn: isarOut));
}

class MainApp extends StatelessWidget {
  MainApp({super.key, required this.isarIn});
  final Isar isarIn;


  final localIsarRepository = LocalIsarRepository(isarIn);

  @override
  Widget build(BuildContext context) {
      return BlocProvider(


Solution

  • This is because you are trying to initialize localIsarRepository with isarIn with the field of declaration in a direct way that is not ok. But you have to initialize localIsarRepository by the constructor of MainApp. by the way you can do it with initState of MainApp if it is stateFullWidget too.

    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
    
      final dir = await getApplicationDocumentsDirectory();
    
      final isarOut = await Isar.open(
        [CostSchema],
        directory: dir.path,
      );
    
      runApp(MainApp(isarIn: isarOut));
    }
    
    class MainApp extends StatelessWidget {
      final Isar isarIn;
      final LocalIsarRepository localIsarRepository;
    
      MainApp({Key? key, required this.isarIn})
          : localIsarRepository = LocalIsarRepository(isarIn), // this is where I explained in above
            super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return BlocProvider(
          create: (context) => YourCubit(localIsarRepository),
          child: MaterialApp(
            home: YourHomePage(),
          ),
        );
      }
    }
    
    class LocalIsarRepository {
      final Isar isar;
    
      LocalIsarRepository(this.isar);
    }
    
    class YourCubit extends Cubit<YourState> {
      final LocalIsarRepository repository;
    
      YourCubit(this.repository) : super(YourInitialState());
    
      // Put your logics of your cubit 
    }
    
    class YourHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Text('Test!!!!'),
          ),
        );
      }
    }
    
    

    About the code:

    the main first initialize the Isar and after that it passes to MainApp then the constructor initialize localIsarRepository. it means that it gets isarIn properly. and your BlocProvider set the Cubit with that repository. by these codes you are not accessing the instance members directly in the field initializers.

    If you had any questions please feel free to ask.

    Happy Coding...