Problems with flutters on status widget after API call
I am having sync issues, I am fetching data from the API, then creating a list from JSON. I think, use the length of the resulting list as the number of items in my watchlist. However, it throws a zero error on the item number and then exits and presents a list scan. I am trying to figure out where the sync issue is and how items and widgets are handled to avoid the error. My code is below in case anyone has any ideas where my code is faulty.
class Specialty extends StatefulWidget {
Specialty({Key key, this.title}) : super(key: key);
final String title;
@override
_SpecialtyState createState() => new _SpecialtyState();
}
class _SpecialtyState extends State<Specialty> {
bool _dataReceived = false;
bool _authenticated = false;
SharedPreferences prefs;
List mylist;
@override
void initState() {
super.initState();
_getPrefs();
_getSpecialty();
}
_getPrefs() async {
prefs = await SharedPreferences.getInstance();
_authenticated = prefs.getBool('authenticated');
print('AUTH2: ' + _authenticated.toString());
print('AUTHCODE2: ' + prefs.getString('authcode'));
}
_getSpecialty() async {
var _url = 'http://$baseurl:8080/support/specialty';
var http = createHttpClient();
var response = await http.get(_url);
var specialties = jsonCodec.decode(response.body);
mylist = specialties.toList();
//_dataReceived = true;
setState(() {
_dataReceived = true;
});
}
Future<Null> _onRefresh() {
Completer<Null> completer = new Completer<Null>();
Timer timer = new Timer(new Duration(seconds: 3), () {
completer.complete();
});
return completer.future;
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new RefreshIndicator(
child: new ListView.builder(
itemBuilder: _itemBuilder,
itemCount: mylist.length,
),
onRefresh: _onRefresh,
));
}
Widget _itemBuilder(BuildContext context, int index) {
Specialties spec = getSpec(index);
return new SpecialtyWidget(spec: spec,);
}
Specialties getSpec(int index) {
return new Specialties(
mylist[index]['id'], mylist[index]['name'], mylist[index]['details'],
new Photo('lib/images/' + mylist[index]['image'], mylist[index]['name'],
mylist[index]['name']));
//return new Specialties.fromMap(mylist[index]);
}
var jsonCodec = const JsonCodec();
}
source to share
You must use await
when calling methods async
. You can mark it initState
as async
, it will still be canceled.
Make sure to call setState()
whenever you mutate member variables.
Check if (mounted)
before setState
if you are doing this after waiting for async because the widget can no longer be visible.
When using asynchronous programming, use FutureBuilder
instead setState
.
source to share