After looking at resources including this SO post, I'm still unsure why my data's not loading on initState:
class _MyAppState extends State<MyApp> {
List<NewsItem> itemList = [];
void _getNews() async {
final news = await http.get(Uri.parse(
'https://newsapi.org/...'));
if (news.statusCode == 200) {
itemList.clear();
var articles = jsonDecode(news.body)['articles'];
for (int i = 0; i < articles.length; i++) {
var newsItem = articles[i];
var item = NewsItem.fromJson(newsItem);
itemList.add(item);
}
} else {
throw Exception('Failed to retrieve news.');
}
}
Future<void> _getData() async {
setState(() {
_getNews();
});
}
@override
void initState() {
super.initState();
_getNews();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'NewsAPI.org Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: const Text("News App")),
body: RefreshIndicator(
onRefresh: _getData,
child: ListView.builder(
itemCount: itemList.length,
itemBuilder: (context, i) {
return GestureDetector(
onTap: () {
if (itemList[i].url != null) {
var _url = itemList[i].url!;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DisplayWebPage(_url)),
);
}
},
child: Card(
elevation: 10,
shadowColor: Colors.black,
child: Padding(
padding: const EdgeInsets.all(10),
child: Column(
children: [
Image.network(itemList[i].urlToImage ?? ''),
Text(itemList[i].title ?? '',
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 14)),
Text(itemList[i].description ?? ''),
const Divider(
color: Colors.black,
height: 25,
thickness: 2,
),
],
),
),
),
);
},
),
),
),
);
}
}
When the app loads, the screen is blank. If I pull to refresh, i.e., call _getData()
, then the expected web data loads. I didn't think calling setState()
during initialization would matter, but I tried calling _getNews()
at startup, too. (Didn't matter.)
What should the code be so that the web data is loaded when the app starts?