having trouble with Flutter setState()

0

im having some issues with the setState method in flutter.

a little backstory: im making a flutter app that displays how many people are in a room via 5 dots that change colour depending on how many people are in said room. it gets its data via HTTP get requests.

i wish to have my dots automatically update their colour based on the data value, i have tried passing the data variable through the setState() method but it wont update.

is there something wrong with the way im using the setState() method or is it something else?

my code:

i have a statefull dot class as shown below

class Dot extends StatefulWidget {
  final int roomnumber;
  final int dotnumber; // number of the dot 0-4
  const Dot({Key? key,required this.roomnumber, required this.dotnumber});

  DotState createState() => DotState();
}

my DotState class looks like this

class Dot extends StatefulWidget {
  final int roomnumber;
  final int dotnumber; // number of the dot 0-4
  const Dot({Key? key,required this.roomnumber, required this.dotnumber});

  DotState createState() => DotState();
}

class DotState extends State<Dot> {

  HttpHandler httpHandler = new HttpHandler();


  @override
  void initState() {
    new Timer(const Duration(seconds: 1), update);
    super.initState();
  }

  var data = 0;

  void update() {
    setState(() {
      // update the data variable so that it holds the most up to date data
    });
  }

  Widget build(BuildContext context) {
    Color dotcolor;
    var colorlist = [0xFF8AF107,0xFFFFF50D,0xFFFFC700,0xFFFF900D,0xFFF5430B];
    var dotdistribution = [0,5,10,20,40,1000];
    var _color = 0xFFFFFFFF;
    data = httpHandler.getDataList().elementAt(widget.roomnumber);

    for (var p=1;p<5;p++) {
      if (data > dotdistribution.elementAt(p)) {
        _color = colorlist.elementAt(p-1);
      }
    }
    if (data > dotdistribution.elementAt(widget.dotnumber))
      dotcolor = Color(_color);
    else dotcolor = Colors.white;
    return Container(
      decoration: BoxDecoration(
        border: Border.all(color: dotcolor),
        // TODO: make statefull
        color: dotcolor,
        borderRadius: BorderRadius.circular(100),
      ),
      width: 15,
      height: 15,
      margin: EdgeInsets.fromLTRB(2.5, 0, 2.5, 0),
    );
  }
}

here is the card class and card state containing all 5 dots

class Card extends StatefulWidget {

  final String name;
  final int roomnumber;
  const Card({Key? key, this.name = '', required this.roomnumber}) : super(key: key);

  @override
  CardState createState() => CardState();
}

class CardState extends State<Card>{

  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Color(0xFFEEEEEEE),
        border: Border.all(color: Colors.white),
          borderRadius: BorderRadius.circular(10),
      ),
      padding: EdgeInsets.all(10.0),
      height: 60,
      child: Row(
        children: <Widget>[
           Expanded(flex: 2,child:
             Container(
               child: Text(
                 widget.name,
                 style: GoogleFonts.inter(
                   fontWeight: FontWeight.bold,
                   fontSize: 18,
                 ),
               )
             )),
           Expanded(child:
             Row(
               children: [
                 for (var n = 0; n < 5; n++) Dot (
                   roomnumber: widget.roomnumber,
                   dotnumber: n,
                 )
               ]
             )
           )
        ],
      ),
    );
  }
}

i have already verified that my httphandler class works as intended so thats not the issue

flutter
http
dart
asked on Stack Overflow May 17, 2021 by MidasVanVeen

1 Answer

0

First of all, you should understand that HTTP requests always won't get a response in 1 second, It's better to say response time isn't constant and depends on a lot of things like network connection quality.

So defining a delay for setting state only works if the response comes before 1 second.

What you should do is waiting for the response to come and then update the state. The best way I can advise for now is using FutureBuilder.

The FutureBuilder widget gets a method that returns a Future value like API callbacks and its build function executes after every event that comes from that method.

You can read more about FutureBuilder in official doc

answered on Stack Overflow May 17, 2021 by Arytan

User contributions licensed under CC BY-SA 3.0