0

I am fairly new to flutter just been a few days.

I am trying my hands on provider pattern, and find it easy to use and understand. However, after implementing i found the button is needed to press twice for the update of state.

I have checked everywhere, like double function call and nothing seems wrong. Here is the code.

    class CounterPage extends StatelessWidget {

  final changeName = TextEditingController();
  final changeNumber = TextEditingController();

  @override
  Widget build(BuildContext context) {
    final CounterBloc counterBloc = Provider.of<CounterBloc>(context);
    return Scaffold(
      appBar: 
      AppBar(
        title: Text(counterBloc.name.toString()),
      ),
      body: Container(
        child: Center(
          child: Column(
            children: <Widget>[
              Text(
                counterBloc.counter.toString(),
                style: TextStyle(fontSize: 62.0),
              ),
              TextField(
                controller: changeName,
              ),
                TextField(
                controller: changeNumber,
              ),
              IncrementButton( changeNumber.text, changeName.text),
            ],
          ),
        ),
      ),
    );
  }
}

The nomenclature is wrong, the use of the increment button is to, just pass two string and set to some places in UI using provider.

This is what my increment button looks like, SImple nothing fancy

   class IncrementButton extends StatelessWidget{

  final String name;
  final String number;
  IncrementButton(this.name, this.number);
  @override
  Widget build(BuildContext context) {
    final CounterBloc counterBloc = Provider.of<CounterBloc>(context);
    return FlatButton.icon(
      icon: Icon(Icons.add),
      label: Text("Add"),
      onPressed: ()=>counterBloc.nameAndCounter(name,number),
    );
  }

}

And this is what counterBloc looks like

   import 'package:flutter/material.dart';

class CounterBloc extends ChangeNotifier{

  String _counter = "10";
  String _name ="Alphhit";

  String get counter => _counter;
  String get name => _name;
   nameAndCounter( String name, String digit){
    _name =  name;
    _counter = digit;

    notifyListeners();
  }
}

The state gets updated and reflected only after pressing the button twice? Can someone please tell what I am doing wrong ?

Alpit Anand
  • 1,213
  • 3
  • 21
  • 37

1 Answers1

3

When you call the IncrementButton( changeNumber.text, changeName.text,), it will start with the previous values so you must update it when you add a new text. You can use onChanged: (_){setState(() {});

Column( children: <Widget>[
              Text(
                counterBloc.counter,
                style: TextStyle(fontSize: 62.0),
              ),
              TextField(
                controller: changeName,
                onChanged: (_){
                  setState(() {
                  });
                },
              ),
                TextField(
                controller: changeNumber,
                onChanged: (_){
                  setState(() {
                  });
                },
              ),
              IncrementButton( changeNumber.text, changeName.text,),
            ],
          ),

Or send the function to the button

    class CounterPage extends StatelessWidget {

  final changeName = TextEditingController();
  final changeNumber = TextEditingController();
  final changeName = TextEditingController();

  final changeNumber = TextEditingController();
   _updateData() {
     Provider.of<CounterBloc>(context).nameAndCounter(changeNumber.text, changeName.text);
  }

  @override
  Widget build(BuildContext context) {
    CounterBloc counterBloc = Provider.of<CounterBloc>(context);
    print(counterBloc.name);
    return Scaffold(
      appBar: AppBar(
        title: Text(counterBloc.name),
      ),
      body: Container(
        child: Center(
          child: Column(
            children: <Widget>[
              Text(
                counterBloc.counter,
                style: TextStyle(fontSize: 62.0),
              ),
              TextField(
                controller: changeName,

              ),
              TextField(
                controller: changeNumber,

              ),
              IncrementButton(_updateData),
            ],
          ),
        ),
      ),
    );
  }
}

class IncrementButton extends StatelessWidget {
  final Function updateData;

  IncrementButton(this.updateData);
  @override
  Widget build(BuildContext context) {
    return FlatButton.icon(
      icon: Icon(Icons.add),
      label: Text("Add"),
      onPressed: updateData,
    );
  }
}
SUX
  • 850
  • 8
  • 21
  • But the whole point of provider is not to setState right ? Do we be really needing a stateful widget – Alpit Anand Nov 24 '19 at 16:18
  • 1
    if you want it to be Stateless use the second way send the function to the button widget. but if you want `onChanged` use stateful – SUX Nov 24 '19 at 16:25
  • Yes i did it by second, without state, u made a statefull widget above, but thank, ur answer really helped me, i dont think i would have figured it out on myself – Alpit Anand Nov 24 '19 at 16:27