TL;DR: My Provider class doesn't trigger a rebuild, but I don't know what I'm doing wrong. Code provided below.
Hi,
I have a ListView.builder nested inside a Consumer.
While it creates as many MyProvider instances I have, if I delete or update an element, it does delete/update that element on the database, but it doesn't trigger a rebuild on the ListView builder, despite using notifyListeners().
This is (a simplified version of) my code:
genre_list.dart
class GenreListScreen extends StatefulWidget { static const routeName = '/genre-list'; @override _GenreListScreenState createState() => _GenreListScreenState(); } class _GenreListScreenState extends State<GenreListScreen> { @override Widget build(BuildContext context) { return Scaffold( appBar: ... ), body: Consumer<GenreProvider>( builder: (context, data, index) { var genres = data.getGenres; return ListView.builder( itemCount: genres.length, itemBuilder: (context, index) { var genre = genres[index]; return ListTile( title: Text(genre['title']), subtitle: IconButton( icon: Icon(Icons.edit), onPressed: () async { try { GenreProvider().updateGenre(genre['id'], 'Testing'); } on Exception catch (_) { showSnackBar( text: 'Unknown error updating the genre.', color: Colors.red, context: context, ); } }, ), ); }, ); }, ), ); } }
genre_provider.dart
class GenreProvider with ChangeNotifier { static List<Map<String, dynamic>> _genres = []; Future fetchGenres() async { try { QuerySnapshot<Map<String, dynamic>> genres = await FirebaseFirestore.instance.collection('genres').get(); _genres = []; genres.docs.forEach((genre) { _genres.add({'id': genre.id, 'title': genre['title']}); }); notifyListeners(); } catch (e) { print(e); } } Future updateGenre(String id, String title) async { try { await FirebaseFirestore.instance .collection('genres') .doc(id) .update({'title': title}); var updatedGenre = _genres.firstWhere((element) => element['id'] == id); updatedGenre['title'] = title; notifyListeners(); } catch (e) { throw (e); } } List<Map<String, dynamic>> get getGenres { return _genres; } }
After a successful login, I call fetchGenres to get the data. Then, I move to GenteListScreen and I can see all the genres I have on my Database.
Clicking on the 'Edit' button, I edit the Genre on the Database (normally a Dialog with a TextFormField, but for the example it is just a fixed string), but it doesn't trigger an UI rebuild on the ListView.
Calling setState(() {}) after the function, triggers a rebuild, and everything is fine, but this call should be done automatically by the Provider package via Consumer.
So the question is: What I am missing on the code to trigger the automatically rebuild?
Top comments (1)
Hi!, David! I'm sorry for being late :)
You should add wrapper with class "ChangeNotifierProvider" in your widget's tree.
According to this example: flutter.dev/docs/development/data-...
Your should get something like this, I think (in attach image)
dev-to-uploads.s3.amazonaws.com/up...