How to declare observable in Mobx flutter to trigger when a field of a class is changed?

2,956

Problem is that you are just changing value of object item(value). You have to completely change object, then only mobx find value is change.

Replace your following line

cello.value = cadence.toString();

With following code:

cello = Cell(
    description: cello.description,
    value: cadence.toString(),
    unit: cello.unit);
Share:
2,956
Zebra
Author by

Zebra

Updated on December 19, 2022

Comments

  • Zebra
    Zebra over 1 year

    I am learning Mobx Flutter and would like to have an observer showing modification of a field in a class.

    When using an int instead of a custom class it is working. So i suspect I am not declaring properly the class in the store

    Here is the code of my store

    import 'package:mobx/mobx.dart';
    
    // generated file
    part 'bikeModel.g.dart';
    
    class Cell {
      String description;
      String value;
      String unit;
    
      Cell({this.description, this.value, this.unit});
    }
    
    class BikeData = _BikeData with _$BikeData;
    
    abstract class _BikeData with Store {
      Timer _timerSimu;
    
      @observable
      int cadence = 0;
    
      @observable
      Cell cello = Cell(description: 'desc', value: 'oo', unit: 'km/h');
    
      @action
      startSimul() {
        int _tick = 0;
        cadence++;
        cello.value = cadence.toString();
        _timerSimu = Timer.periodic(Duration(seconds: 1), (timer) {
          print('Screen simu is ticking...$_tick');
          _tick++;
          cadence++;
        });
      }
    
      @action
      stopSimu() {
        _timerSimu.cancel();
      }
    }
    

    and here is the main code

    import 'package:flutter/material.dart';
    import 'package:flutter_mobx/flutter_mobx.dart';
    import 'package:mobx_first/bikeModel.dart';
    
    import 'globals.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'MobX',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      const MyHomePage();
    
      @override
      Widget build(BuildContext context) {
        BikeData store = BikeData();
    
        return GestureDetector(
          onPanUpdate: (details) {
            if (details.delta.dx > 0) {
              // Right swipe
              print('this is a right swipe');
            } else {
              // left swipe
              print('this is a left swipe');
            }
          },
          child: Scaffold(
            appBar: AppBar(
              title: Text('MobX Test'),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Observer(
                      builder: (_) => Text('cello.value ${store.cello.value}')),
                  Observer(builder: (_) => Text('cadence ${store.cadence}')),
                ],
              ),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: store.startSimul,
              tooltip: 'Change',
              child: Icon(Icons.add),
            ),
          ),
        );
      }
    }
    

    cadence is changing everything second on the screen but not cello.value

    What is the proper way to declare cello observable?

  • Zebra
    Zebra about 4 years
    Yes it works now. Thanks for helping to better understand Mobx!
  • Taha Malik
    Taha Malik about 2 years
    Yeah, I also had to recreate the object in order to make observers rebuild. But Can't we do it without recreating objects?
  • Viren V Varasadiya
    Viren V Varasadiya about 2 years
    I am not sure but you can use equatable package to compare your object and I think then it will work.