Matt Takao
Matt Takao

Reputation: 3006

Flutter: update PaginatedDataTable from method in DataTableSource?

I think I'm close to solving this but not sure how to do it, and perhaps there is a better way altogether.

I have this WeightDataSource, the WeightDialog will simply return a number that the user inputs. The values are properly being stored in memory, but of course the screen is not updating because the state in the other class hasn't changed (if I reload the app I can see the changes).

class WeightDataSource extends DataTableSource {
  final List<Weight> _weights;
  final BuildContext context;

  WeightDataSource(this.context, this._weights);

  int _selectedCount = 0;

  _editCell(index, Weight _weight) async {
    print('$index $_weight');
    var updatedWeight = await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (BuildContext context) =>
              WeightDialog(
                color: Colors.greenAccent,
                saveUpdate: 'update',
              ),
          fullscreenDialog: true,
        ));
    if (updatedWeight != null) {
      print('received weight: $updatedWeight');
      final prefs = await SharedPreferences.getInstance();
      var tempWeights = json.decode(prefs.getString('weights')) ?? {};
      tempWeights[_weight.date.toString()] = updatedWeight;
      prefs.setString('weights', json.encode(tempWeights));
      tempWeights = json.decode(prefs.getString('weights')) ?? {};
      print('updated weights $tempWeights');
    }
  }

// ...

My thinking is if I can just call my _loadAsyncData function somehow, the screen will update, but I'm not sure how to do that from a different class:

class HistoryPageState extends State<HistoryPage> {
  var calories = {};
  var weights = {};

  @override
  void initState() {
    super.initState();
    _loadAsyncData();
  }

  _loadAsyncData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      calories = json.decode(prefs.getString('calories')) ?? {};
      weights = json.decode(prefs.getString('weights')) ?? {};
    });
  }

  // ...

  _updateWeights(BuildContext context, _weightsDataSource) async {
    var inputCalories = await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) =>
              Scaffold(
                appBar: AppBar(title: Text('Update weights')),
                body: PaginatedDataTable(
                  header: Text('Weight Log'),
                  dataRowHeight: 30,
                  headingRowHeight: 30,
                  rowsPerPage: 3,
                  columns: <DataColumn>[
                    DataColumn(
                      label: Text('Date'),
                    ),
                    DataColumn(label: Text('Weight'))
                  ],
                  source: _weightsDataSource,
                ),
              ),

          fullscreenDialog: true,
        ));

    if (inputCalories != null) {
      print(inputCalories);
    }
  }

Upvotes: 1

Views: 2126

Answers (1)

ccc
ccc

Reputation: 2385

Did you try to call notifyListeners() on the data source ? That's what worked for me.

I think in your case it would have to be in the _editCell() method.

Upvotes: 2

Related Questions