I'm expecting a JSON object of data but instead am getting Instance of 'Post'
I'm new to flutter and trying to hit an API with a post request using http.dart package. I'm using an async future and a future building to populate a widget with the returned data (following the flutter example here: https://flutter.io/docs/cookbook/networking/fetch-data).
Future<Post> fetchPost() async {
String url = "https://example.com";
final response = await http.post(url,
headers: {HttpHeaders.contentTypeHeader: 'application/json'},
body: jsonEncode({"id": "1"}));
if (response.statusCode == 200) {
print('RETURNING: ' + response.body);
return Post.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load post');
}
}
class Post {
final String title;
Post({this.title});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
title: json['title']
);
}
}
void main() => runApp(MyApp(post: fetchPost()));
class MyApp extends StatelessWidget {
final Future<Post> post;
MyApp({Key key, this.post}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder<Post>(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.toString());
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return CircularProgressIndicator();
},
),
),
),
);
}
}
I'm expecting the return statement in the FutureBuilder to give me a json object. This is an existing API so I know it works and it returns what I'm expecting.
I am not sure what you refer to when you say "JSON object". Dart is a typed language and the way you represent anything coming as a json string is either a nested Map<String, dynamic>
or a class (like in your case). If it is a class there is code that performs the actual de-/serialization. In your case the fromJson method in conjunction with the json.decode() can do the deserialization, but you have nothing for serialization yet.
So your future builder is returning what you ask it to. The following piece of code defines the type of future clearly returning a Post
object:
final Future<Post> post;
and you use it when creating your future builder:
child: FutureBuilder<Post>(
future: post,
If you want a JSON String
(or a Map<String,dynamic>
) returned you need to start by doing that in your fetchPost
method (which currently is also returning a Post
object.
For example:
Future<Map<String, dynamic>> fetchPost() async { // <------ CHANGED THIS LINE
String url = "https://example.com";
final response = await http.post(url,
headers: {HttpHeaders.contentTypeHeader: 'application/json'},
body: jsonEncode({"id": "1"}));
if (response.statusCode == 200) {
print('RETURNING: ' + response.body);
return json.decode(response.body); // <------ CHANGED THIS LINE
} else {
throw Exception('Failed to load post');
}
}
or like this:
Future<String> fetchPost() async { // <------ CHANGED THIS LINE
String url = "https://example.com";
final response = await http.post(url,
headers: {HttpHeaders.contentTypeHeader: 'application/json'},
body: jsonEncode({"id": "1"}));
if (response.statusCode == 200) {
print('RETURNING: ' + response.body);
return response.body; // <------ CHANGED THIS LINE
} else {
throw Exception('Failed to load post');
}
}
Then you need to work your way up until you change the Future in your MyApp class.
final Future<Map<String,dynamic>> post;
Please read these docs to learn about JSON in flutter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With