Why my Flutter JSON data didn't updated from setState?

245

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 :)

Share:
245
Bill Rei
Author by

Bill Rei

Updated on December 29, 2022

Comments

  • Bill Rei
    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
    Bill Rei about 3 years
    Hmmm, 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
    Kami Tzayig about 3 years
    Sure! 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