flutterdartmobx

How do I need write periodic timer to test connection to the server using Mobx?


I want to write the ReactionBuilder with Mobx, which will check a connection with my server periodicly and do new request to connect it if there is not a connection. How can I do it correctly?

I have the next state class of a page which contains a function to test connection with my backend server:

abstract class LandingPageStateBase with Store {
  final IempServerRepositoryBase _iempServerRepository;
  var counterTryToConnect = 0;

  ...

  @observable
  bool isLoading = false;

  ...

  @action
  Future<void> getTestConnection() async {
    counterTryToConnect += 1;
    isLoading = true;
    connection = null;

    try {
      final data = await _iempServerRepository.getConnection();
      connection = data;
    } on Exception catch (_) {
      connection = null;
    }

    isLoading = false;
  }

  bool isConnected() {
    return connection != null && !isLoading;
  }
}

And a part of widget page:

@override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
        child: SafeArea(
      child: ReactionBuilder(
        builder: (context) {
          _landingPageState.getTestConnection();
          // HERE I NEED TO CHECK CONNECTION AND DO IT AGAIN IF NOT CONNECTED
          return reaction((_) => _landingPageState.isLoading, (_) {
            if (!_landingPageState.isConnected() &&
                _landingPageState.counterTryToConnect < 4) {
              _landingPageState.getTestConnection();
            } else if (_landingPageState.isConnected()) {
              Future.delayed(const Duration(milliseconds: 500), () {
                setState(() {
                  Navigator.pushReplacement(
                      context,
                      CupertinoPageRoute(
                          builder: (context) => const LogInPage()));
                });
              });
            }

            debugPrint('debug: ${_landingPageState.counterTryToConnect}');
          }, delay: 1000);
        },
    ...

I don't consider options using Stream, because I use the concept of working with Mobx and do not want to mix different approaches with reactivity. I just wanna understand how I can do it with Mobx.


Solution

  • I solved the problem the next way:

    abstract class LandingPageStateBase with Store {
      final IempServerRepositoryBase _iempServerRepository;
    
      LandingPageStateBase(this._iempServerRepository);
    
      final _maxRetryToConnectCount = 10;
      int retryToConnectCount = 0;
    
      Connection? connection;
    
      @observable
      ConnectionState connectionState = ConnectionState.waiting;
    
      @action
      Future<void> connectToServer() async {
        connectionState = ConnectionState.waiting;
    
        try {
          final data = await _iempServerRepository.getConnection();
          connection = data;
          connectionState = ConnectionState.done;
        } catch (_) {}
    
        if (connectionState == ConnectionState.done) {
          retryToConnectCount = 0;
        } else {
          retryToConnectCount++;
    
          if (retryToConnectCount < _maxRetryToConnectCount) {
            await Future.delayed(const Duration(seconds: 2));
            connectToServer();
          } else {
            connectionState = ConnectionState.none;
          }
        }
      }
    }
    

    And the page's widget:

    child: ReactionBuilder(
            builder: (context) {
              _landingPageState.connectToServer();
              return reaction((_) => _landingPageState.connectionState, (_) {
                if (_landingPageState.connectionState == ConnectionState.done) {
                  Future.delayed(const Duration(milliseconds: 500), () {
                    setState(() {
                      Navigator.pushReplacement(
                          context,
                          CupertinoPageRoute(
                              builder: (context) => const LogInPage()));
                    });
                  });
                }
                debugPrint('debug: ${_landingPageState.connectionState.name}');
              }, delay: 2000);
            },