I have this singleton:
final class OpenWeather {
final String baseURL, apiKey, baseWeatherIconUrl;
const OpenWeather._({required this.baseURL, required this.apiKey, required this.baseWeatherIconUrl});
static OpenWeather? _instance;
static Future<void> init() async {
if (_instance != null) return;
try {
await dotenv.load(fileName: 'my.env');
_instance = OpenWeather._(
baseURL: dotenv.get('BASE_API_URL'),
apiKey: dotenv.get('API_KEY'),
baseWeatherIconUrl: dotenv.get('BASE_WEATHER_ICON_URL'),
);
} catch (e) {
_instance = null;
throw Exception('Env file cannot be loaded or some required field was not found.');
}
}
static OpenWeather get instance {
if (_instance != null) return _instance!;
throw Exception('OpenWeather was not initialized.');
}
}
I'm new with this package so I'm getting a hard time about how to transform this class to use it with Injection package.
Another question is about how to notify other singletons to await to be created until an instance of OpenWeather exists (after init
async method to be executed), example:
@singleton
class MyClass {
void myMethod() {
final value = OpenWeather.instance.baseURL;
...
<code using this value>
...
}
}
PS 1. my n-try:
@singleton
final class OpenWeather {
final String baseURL, apiKey, baseWeatherIconUrl;
const OpenWeather({required this.baseURL, required this.apiKey, required this.baseWeatherIconUrl});
@factoryMethod
static Future<OpenWeather> init() async {
try {
await dotenv.load(fileName: 'my.env');
return OpenWeather(
baseURL: dotenv.get('BASE_API_URL'),
apiKey: dotenv.get('API_KEY'),
baseWeatherIconUrl: dotenv.get('BASE_WEATHER_ICON_URL'),
);
} catch (e) {
throw Exception('Env file cannot be loaded or some required field was not found.');
}
}
}
@singleton
class MyClass {
final OpenWeather openWeather;
void myMethod(this.openWeather) {
final value = openWeather.baseURL;
...
<code using this value>
...
}
}
import 'di.config.dart';
final getIt = GetIt.instance;
@InjectableInit(
preferRelativeImports: true,
)
void configureDependencies() => getIt.init();
void main() async {
configureDependencies();
runApp(const AppProviders(child: MyApp()));
}
When running dart run build_runner build --delete-conflicting-outputs
, it seems to be all OK so to check it I wanted to print a singleton value to my console from the home file of my app:
@RoutePage()
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
final baseUrl = getIt<OpenWeather>().baseURL;
print('baseUrl: $baseUrl');
return Scaffold(
...
But I get this error message:
Launching lib/main.dart on Pixel 3a in debug mode...
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Connecting to VM Service at ws://127.0.0.1:46799/xrh7AgjvmbE=/ws
════════ Exception caught by widgets library ═══════════════════════════════════
The following StateError was thrown building HomeScreen(dirty):
Bad state: You tried to access an instance of OpenWeather that is not ready yet
The relevant error-causing widget was:
HomeScreen HomeScreen:file:.../flutter_weather2/lib/config/routes/app_router.gr.dart:30:22
When the exception was thrown, this was the stack:
#0 throwIfNot (package:get_it/get_it_impl.dart:12:19)
#1 _GetItImplementation.get (package:get_it/get_it_impl.dart:434:7)
#2 _GetItImplementation.call (package:get_it/get_it_impl.dart:464:12)
#3 SearchScreen.build (package:flutter_weather2/modules/weather/3_presentation/2_screens/home/home_screen.dart:16:26)
#4 StatelessElement.build (package:flutter/src/widgets/framework.dart:5541:49)
#5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5471:15)
#6 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5453:5)
#8 ComponentElement.mount (package:flutter/src/widgets/framework.dart:5447:5)
... Normal element mounting (25 frames)
#33 Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#34 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6871:36)
#35 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6883:32)
... Normal element mounting (50 frames)
#85 Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#86 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6871:36)
#87 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6883:32)
... Normal element mounting (362 frames)
#449 Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#450 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6871:36)
#451 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6883:32)
... Normal element mounting (77 frames)
#528 Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#529 Element.updateChild (package:flutter/src/widgets/framework.dart:3831:20)
#530 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16)
#531 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11)
#532 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#533 StatefulElement.update (package:flutter/src/widgets/framework.dart:5657:5)
#534 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15)
#535 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16)
#536 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#537 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5)
#538 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15)
#539 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16)
#540 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#541 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5)
#542 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15)
#543 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16)
#544 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11)
#545 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#546 StatefulElement.update (package:flutter/src/widgets/framework.dart:5657:5)
#547 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15)
#548 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16)
#549 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#550 StatelessElement.update (package:flutter/src/widgets/framework.dart:5547:5)
#551 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15)
#552 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16)
#553 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#554 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5)
#555 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15)
#556 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16)
#557 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#558 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5)
#559 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15)
#560 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16)
#561 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11)
#562 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#563 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2895:19)
#564 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:984:21)
#565 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:457:5)
#566 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325:15)
#567 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1255:9)
#568 SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:978:7)
#572 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
(elided 3 frames from class _Timer and dart:async-patch)
════════════════════════════════════════════════════════════════════════════════
So Where/which is the problem?