I wrote a simple webpage widget in Flutter which tries to fetch simple JSON from a public web API but it fails on the very line where it fetches the data. The error message doesn't say anything specific. What am I doing wrong?
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as customhttp;
import '../settings/schemes/color_scheme.dart';
class ContentPage extends StatefulWidget {
const ContentPage({super.key});
@override
State<ContentPage> createState() => _ContentPageState();
}
class _ContentPageState extends State<ContentPage> {
var _posts = [];
Future fetchPosts() async {
try
{
String url = "https://jsonplaceholder.typicode.com/posts";
final customhttp.Response response = await customhttp.get(Uri.parse(url));
final List<dynamic> jsonData = json.decode(response.body) as List;
setState(() {
_posts = jsonData;
});
print("Got JSON data.");
print(_posts[0]);
} catch (err) {}
}
@override
void initState() {
super.initState();
fetchPosts();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: schemeBackgroundColor,
body: Container(
child: Text("JSON DATA:\n ${_posts[0]}"),
),
);
}
}
The error I'm getting on line 20:
CodePudding user response:
The error is in the widget.
You are trying to display the first item of the posts even before getting the data.
Text("JSON DATA:\n ${_posts[0]}"),
You should either use FutureBuilder or check if the list is emplty or not before displaying the item.
Example:
Text("JSON DATA:\n ${_posts.isEmpty ? 'No Data' : _posts[0]}"),
CodePudding user response:
OK, I think I might found your problem. When I pasted the code all works well BUT sometimes it doesn't do to the fact that your widget builds before you get the data so hence the error. You might wanna try with this:
Text("JSON DATA:\n ${_posts.isEmpty ? 'There is no data' : _posts[0]}")
Or you can use a FutureBuilder()
:
FutureBuilder(
future: fetchPosts(),
builder: (context, dataSnapshot) {
if (dataSnapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
if (dataSnapshot.error != null) {
return Center(
child: Text('An error occured'),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, i) => Text("JSON DATA:\n ${snapshot.data[i]}"),
),
);
}
}
},
),
If this doesn't work, let me know so I can find an another solution.