Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MOdule binds AsyncBind in version 6 #894

Open
PabloAznarez opened this issue Aug 30, 2023 · 4 comments
Open

MOdule binds AsyncBind in version 6 #894

PabloAznarez opened this issue Aug 30, 2023 · 4 comments
Labels
new New issue request attention question Questions about using some feature or general working of the package

Comments

@PabloAznarez
Copy link

Describe the question
In the documentation I have not been able to find the way to migrate from version 5 to 6 in this case:

List get binds => [AsyncBind((i) => Database.initDatabase())];

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots or videos to help explain your problem.

@PabloAznarez PabloAznarez added new New issue request attention question Questions about using some feature or general working of the package labels Aug 30, 2023
@eduardoflorence
Copy link

@PabloAznarez, AsyncBind was removed in version 6.

Changelog:
DEPRECATED: modular_test package. Please check the Test section of documentation.
DEPRECATED: bloc_modular_bind package. Please check the Watch section of documentation.
DEPRECATED: triple_modular_bind package. Please check the Watch section of documentation.
Removed: WidgetModule;
Removed: ModularState;
Removed: AsyncBind;

@fullflash
Copy link

changelog just informs about removal of AsyncBind
would be nice to provide migration example

@eduardoflorence
Copy link

Hi @fullflash, see this:

import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';

void main() {
  runApp(ModularApp(module: AppModule(), child: const AppWidget()));
}

class AppWidget extends StatelessWidget {
  const AppWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: Modular.routerConfig,
    );
  }
}

class Config {
  Config._();
  static final Config _instance = Config._();

  late String baseURL;
  late String token;

  Future<void> init() async {
    // Gets async settings
    await Future.delayed(const Duration(seconds: 2));
    baseURL = 'https://myapy.com';
    token = 'asdfg12345';
  }

  static Config setup() {
    return _instance;
  }
}

class Dio {}

class DioOptionsSetup {
  final Dio dio = Dio();
  // Dio configurations

  Dio getInstance() {
    return dio;
  }
}

class ApiClient {
  ApiClient({required this.dio});
  final Dio dio;
}

class AppModule extends Module {
  @override
  void binds(i) {
    i.add(() => Config.setup());
    i.add(DioOptionsSetup.new);
    i.add(() => ApiClient(dio: i<DioOptionsSetup>().getInstance()));
  }

  @override
  void routes(r) {
    r.child('/', child: (context) => const SplashPage());
    r.child('/home', child: (context) => HomePage(config: Modular.get<Config>()));
  }
}

class SplashPage extends StatefulWidget {
  const SplashPage({super.key});

  @override
  State<SplashPage> createState() => _SplashPageState();
}

class _SplashPageState extends State<SplashPage> {
  @override
  void initState() {
    super.initState();
    Future(startServices);
  }

  Future<void> startServices() async {
    final config = Modular.get<Config>();
    await config.init();
    Modular.to.navigate('/home');
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: CircularProgressIndicator(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key, required this.config});

  // constructor dependency injection example
  final Config config;

  @override
  Widget build(BuildContext context) {
    // dependency example by service locator
    final apiClient = Modular.get<ApiClient>();
    return Scaffold(
      appBar: AppBar(title: const Text('Home Page')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Base URL: ${config.baseURL}'),
            Text('Token: ${config.token}'),
            Text('ApiCliente: ${apiClient.toString()}'),
          ],
        ),
      ),
    );
  }
}

@RodolfoSilva
Copy link
Contributor

This is how I am currently using in my app:

Create a BootService

import 'dart:async';

class BootService {
  final Completer _completer = Completer();
  bool _initialized = false;

  Future get future {
    // This will avoid the BootService to be initialized multiple times
    if (!_initialized) {
      _initialized = true;
      _boot().then((value) => _completer.complete());
    }
    return _completer.future;
  }

  Future _boot() async {
    // Add your long-running initialization process here...
    await Future.delayed(const Duration(seconds: 3));
  }
}

Declare this service as a singleton within the AppModule.

import 'package:flutter_modular/flutter_modular.dart';

import '../core/services/boot_service.dart';

class AppModule extends Module {
  @override
  void binds(i) {
    i.addSingleton(BootService.new);
  }

  // Continuation of your module implementation...
}

Now in your AppWidget you can use something like this:

import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';

import '../core/services/boot_service.dart';

class AppWidget extends StatelessWidget {
  const AppWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: Modular.get<BootService>().future,
      builder: (context, snapshot) {
        if (snapshot.connectionState != ConnectionState.done) {
          return WidgetsApp(
            color: Colors.white,
            builder: (context, child) => const Material(
              child: Center(
                child: Text('Loading...'),
              ),
            ),
          );
        }

        return MaterialApp.router(
          title: 'MyApp',
          routerConfig: Modular.routerConfig,
        );
      },
    );
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new New issue request attention question Questions about using some feature or general working of the package
Projects
None yet
Development

No branches or pull requests

4 participants