Reputation: 83
I want to fetch data from an API and set those data to the central state(provider) after creating a screen.( similar scenario of react useEfect function)
class MyApp2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Counter>(
child: MyHomePage(title: 'Flutter Demo Home Page'),
create: (BuildContext context) => Counter());
}
}
class _MyHomePageState extends State<MyHomePage> {
void _incrementCounter(dynamic count) {
count.incrementCounter();
}
int fetchData() {
//api request code
return data; // return fetched data
}
@override
Widget build(BuildContext context) {
final count = Provider.of<Counter>(context);
count.setCounter(fetchData());
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${count.counter}',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => _incrementCounter(count),
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class Counter with ChangeNotifier{
int counter= 0;
void setCounter(int x){
counter =x;
notifyListeners();
}
void clearCounter(){
counter =0;
notifyListeners();
}
void incrementCounter(){
counter++;
notifyListeners();
}
}
It throws and exception and it doesn't work.
setState() or markNeedsBuild() called during build.
If I remove the notifyListeners() function, the app runs without any exceptions but the widget what I want to rebuild isn't rebuilt.
void setCounter(int x){
counter =x;
// notifyListeners();
}
What is the best way to do that?
Upvotes: 2
Views: 1925
Reputation: 15103
I am also new to Provider
. So this may not be a good solution.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp2(),
);
}
}
class MyApp2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Counter>(
child: MyHomePage(title: 'Flutter Demo Home Page'),
create: (BuildContext context) => Counter(),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({Key key, this.title}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Consumer<Counter>(
builder: (context, counter, _) {
if (counter.waiting)
return CircularProgressIndicator();
else
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Consumer<Counter>(
builder: (context, counter, _) {
return Text(
'${counter.counter}',
style: Theme.of(context).textTheme.display1,
);
},
),
],
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: Provider.of<Counter>(context).incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class Counter with ChangeNotifier {
int _counter;
bool _waiting;
Counter(){
_waiting = true;
_fetchCounterFromApi();
}
Future<void>_fetchCounterFromApi() async{
_counter = await Future<int>.delayed(Duration(seconds: 2),() => 4);//Do Api request;
_waiting = false;
notifyListeners();
}
int get counter => _counter;
bool get waiting => _waiting;
void incrementCounter() {
_counter++;
notifyListeners();
}
}
Upvotes: 1