I'm trying to get posts from this link: reddit.com/r/flutterdev/new.json
When building FutureBuilder I get an error. I don't know what exactly I do wrong. Maybe there is an error in serialization or I somehow put the data in Text incorrectly.
JSON serialization looks like this:
@JsonSerializable()
class PostsList {
List<PostData> children;
PostsList({required this.children});
factory PostsList.fromJson(Map<String, dynamic> json) =>
_$PostsListFromJson(json);
}
@JsonSerializable()
class PostData {
List<Post> data;
PostData({required this.data});
factory PostData.fromJson(Map<String, dynamic> json) =>
_$PostDataFromJson(json);
}
@JsonSerializable()
class Post {
final String title;
final String? thumbnail;
final String? ups;
final String? selftext;
Post({required this.title, this.thumbnail, this.ups, this.selftext});
factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
}
HomePage and FutureBuilder:
class _MyHomePageState extends State<MyHomePage> {
late Future<PostsList> postsList;
@override
void initState() {
super.initState();
postsList = getPostsList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<PostsList>(
future: postsList,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data?.children.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(
'${snapshot.data?.children[index].data[index].title}'),
),
);
});
} else if (snapshot.hasError) {
return throw Exception();
}
return const Center(child: CircularProgressIndicator());
},
),
);
}
}
Future<PostsList> getPostsList() async {
const url = 'https://reddit.com/r/flutterdev/new.json';
final response = await http.get(Uri.parse(url));
print(
'Status code: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}');
if (response.statusCode == 200) {
return PostsList.fromJson(json.decode(response.body));
} else {
throw Exception('Error: ${response.reasonPhrase}');
}
}
Exception:
════════ Exception caught by widgets library ═══════════════════════════════════
The following _Exception was thrown building FutureBuilder<PostsList>(dirty, state: _FutureBuilderState<PostsList>#ff4f3):
Exception
The relevant error-causing widget was
FutureBuilder<PostsList>
package:testovoe_finam/main.dart:44
When the exception was thrown, this was the stack
#0 _MyHomePageState.build.<anonymous closure>
package:testovoe_finam/main.dart:59
#1 _FutureBuilderState.build
package:flutter/…/widgets/async.dart:615
#2 StatefulElement.build
package:flutter/…/widgets/framework.dart:4919
#3 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4806
#4 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:4977
#5 Element.rebuild
package:flutter/…/widgets/framework.dart:4529
#6 BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2659
#7 WidgetsBinding.drawFrame
package:flutter/…/widgets/binding.dart:891
#8 RendererBinding._handlePersistentFrameCallback
package:flutter/…/rendering/binding.dart:370
#9 SchedulerBinding._invokeFrameCallback
package:flutter/…/scheduler/binding.dart:1146
#10 SchedulerBinding.handleDrawFrame
package:flutter/…/scheduler/binding.dart:1083
#11 SchedulerBinding._handleDrawFrame
package:flutter/…/scheduler/binding.dart:997
#15 _invoke (dart:ui/hooks.dart:151:10)
#16 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308:5)
#17 _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
════════════════════════════════════════════════════════════════════════════════
Try this:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class _MyHomePageState extends State<MyHomePage> {
PostsList? _list;
bool _isLoading = true;
bool _hasError = false;
@override
void initState() {
super.initState();
getPostsList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _isLoading && !_hasError
? const Center(child: CircularProgressIndicator())
: !_isLoading && _hasError
? Column(children: [
Text("Error"),
TextButton(
child: Text("refresh"),
onPressed: () async {
await getPostsList();
},
)
])
: ListView.builder(
itemCount: _list.children.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(
'${_list!.children[index].title}'), // Try to access the data
),
);
}));
}
getPostsList() async {
setIsLoading(true);
setHasError(false);
try {
const url = 'https://reddit.com/r/flutterdev/new.json';
final response = await http.get(Uri.parse(url));
print(
'Status code: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}');
if (response.statusCode == 200) {
setList(response.body);
setIsLoading(false);
} else {
throw Exception('Error: ${response.reasonPhrase}');
setHasError(true);
setIsLoading(false);
}
} catch (_) {
setHasError(true);
setIsLoading(false);
}
}
setList(data) {
if (mounted)
setState(() {
_list = PostsList.fromJson(json.decode(data));
});
}
setIsLoading(bool value) {
if (mounted)
setState(() {
_isLoading = value;
});
}
setHasError(bool value) {
if (mounted)
setState(() {
_hasError = value;
});
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.