I have a FutureBuilder
receiving values from a function. This is my FutureBuilder
with the new context.watch
syntax
final dataNotifier = Provider.of<DataNotifier>(context, listen: false);
returnFutureBuilder(
future: DataService().getData(dataNotifier),
// ignore: missing_return
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Center(child: Text('No status', style: TextStyle(color: Colors.white),));
break;
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
break;
case ConnectionState.done:
return Center(
child: Column(
children: [
Text(context.watch<Data>().myList[0].id, style: TextStyle(color: Colors.white)),
Text(context.watch<Data>().myList[0].name, style: TextStyle(color: Colors.white))
],
));
//Center(child: Text('Data', style: TextStyle(color: Colors.white),));
break;
default:
}
},
),
Everything just works fine as long I'm always passing the dataNotifier
in every function. I'm not quite familiar with providers yet, how can I get that work without always passing the dataNotifier
?
I assume I have to add something in my Changenotifier class? my future function getData(dataNotifier)
ends with the following:
dataNotifier.myList = _myList;
And my Changenotifier
class DataNotifier
:
class DataNotifier with ChangeNotifier {
List<Data> _myList = [];
UnmodifiableListView<Data> get myList => UnmodifiableListView(_myList);
set myList(List<Data> myList){
_myList = myList;
notifyListeners();
}
The simplest working Provider example with a MVVM (Model, View, ViewModel) architecture is this below.
When data is loaded app is updated to display the new value.
You can replace the String data with anything you like, for example a list of items.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MaterialApp(
home: Material(
child: ChangeNotifierProvider<DataNotifier>(
create: (_) => DataNotifier(), child: MyApp()),
)));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final dataNotifier = Provider.of<DataNotifier>(context);
if (dataNotifier.dataLoaded) return Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Text(dataNotifier.data),
Text(
dataNotifier.listData.fold("LIST: ", (previousValue, e) => "$previousValue [${e.id} ${e.name}]"),
)]);
return Text("Waiting...");
}
}
class DataNotifier with ChangeNotifier {
bool _dataLoaded;
bool get dataLoaded => _dataLoaded;
DataService _service;
String _data;
String get data => _data;
List<SampleData> _listData;
List<SampleData> get listData => _listData;
DataNotifier() {
_dataLoaded = false;
_service = DataService();
getData();
}
void getData() async {
_data = await _service.getData();
_listData = await _service.getListData();
_dataLoaded = true;
notifyListeners();
}
}
class DataService {
Future<String> getData() async {
return Future<String>.delayed(
const Duration(seconds: 5),
() => 'Data Loaded',
);
}
Future<List<SampleData>> getListData() async {
return Future<List<SampleData>>.delayed(
const Duration(seconds: 5),
() => List.generate(100, (index) => SampleData(index, "name_$index")),
);
}
}
class SampleData {
int id;
String name;
SampleData(this.id, this.name);
}