Why my Flutter JSON data didn't updated from setState?
the thing is that when you call setState you run build again, and that in turn runs the FutureBuilder again with the original Doa object.
you need to keep a variable that will hold the changes in your _MainPageState outside the build method, theres a few ways to do that and in your case its a little more complicated because you need the context in your fetchDoa.
one workaround is creating a doaList variable to hold the fetched data outside the build and changing the fetchDoa function to set the doaList instead of returning it(that's why it's Future now. but that's not enough because the FutureBuilder will just set the doaList from scrach every time build runs, so we'll add a _isInit bool to check if its the first time running build. after that you should replace all the 'snapshot.data' with doaList as the snapshot holds nothing
class _MainPageState extends State<MainPage> {
List<Doa> doaList;
bool _isInit = true;
Future<void> fetchDoa(BuildContext context) async {
final jsonstring =
await DefaultAssetBundle.of(context).loadString('assets/doa.json');
doaList = doaFromJson(jsonstring);
_isInit = false;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("JSON Data test"),
),
body: Container(
child: FutureBuilder(
future: _isInit? fetchDoa(context): Future(),
builder: (context, _) {
try this and tell me if it works :)
Bill Rei
Updated on December 29, 2022Comments
-
Bill Rei over 1 year
I've made the JSON data and appear it into FutureBuilder with ListView.builder widget. I want to create a favorite Icon in the trailing of the ListView.builder. So i created it with IconButton, but when I create setState to make some item as favorited, the data didn't updated.
Here is my code
import 'package:flutter/material.dart'; import 'package:json_test/class/doa.dart'; import 'package:json_test/page/DoaPage.dart'; class MainPage extends StatefulWidget { @override _MainPageState createState() => _MainPageState(); } class _MainPageState extends State<MainPage> { Future<List<Doa>> fetchDoa(BuildContext context) async { final jsonstring = await DefaultAssetBundle.of(context).loadString('assets/doa.json'); return doaFromJson(jsonstring); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("JSON Data test"), ), body: Container( child: FutureBuilder( future: fetchDoa(context), builder: (context, snapshot) { if (snapshot.hasData) { return ListView.builder( itemCount: snapshot.data.length, itemBuilder: (BuildContext context, int index) { Doa doa = snapshot.data[index]; return Card( margin: EdgeInsets.all(8), child: ListTile( title: Text(doa.judul), onTap: () { Navigator.of(context).push(MaterialPageRoute( builder: (BuildContext context) => DoaPage( doa: doa, ))); }, trailing: IconButton( icon: Icon( doa.fav ? Icons.favorite : Icons.favorite_border, color: doa.fav ? Colors.red : null, ), onPressed: () => setState(() => doa.fav = !doa.fav), ))); }, ); } return CircularProgressIndicator(); }))); } }
and this is the preview
-
Bill Rei about 3 yearsHmmm, im sorry because i still newbie in Flutter. Do you have some advice for me to store data in Flutter application ? Because if I click the Love icon in this app, after I close and open again the application, the Favorited data will be lost :(
-
Kami Tzayig about 3 yearsSure! if you want to save it outside the device, so when you close the app and open it again you will still keep your state( the Love icon would stay favorited), you need to either store the data on your device or use a database like Firebase. if you store it on your device and log in from another device you would lose the data of course. because its a long explanation i cant do in this comment. try to read about SharedPrefrences package and Firebase