Skip to content

Instantly share code, notes, and snippets.

@austinevick
Created September 30, 2023 03:36
Show Gist options
  • Save austinevick/b6d5fbfd77a8238ca82ea4e66078a2d1 to your computer and use it in GitHub Desktop.
Save austinevick/b6d5fbfd77a8238ca82ea4e66078a2d1 to your computer and use it in GitHub Desktop.
Flutter paginated list with rest API
import 'dart:convert';
import 'package:http/http.dart'; //Add http package to pubspec.yaml
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; //Add infinite_scroll_pagination package to pubspec.yaml
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final int limit = 10;
final PagingController<int, PostData> controller =
PagingController(firstPageKey: 1);
@override
void initState() {
controller.addPageRequestListener((pageKey) {
fetchPage(pageKey);
});
super.initState();
}
Future<void> fetchPage(int pageKey) async {
try {
final newItems = await fetchData(pageKey, limit);
final isLastPage = newItems.length < limit;
if (isLastPage) {
controller.appendLastPage(newItems);
} else {
final nextPageKey = pageKey + 1;
controller.appendPage(newItems, nextPageKey);
}
} catch (error) {
controller.error = error;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: PagedListView<int, PostData>.separated(
pagingController: controller,
builderDelegate: PagedChildBuilderDelegate<PostData>(
animateTransitions: true,
itemBuilder: (context, item, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
title: Text(item.content!),
),
)),
separatorBuilder: (context, index) => const Divider(),
),
);
}
}
const baseUrl = 'http://127.0.0.1:3000/api/blog';
Future<List<PostData>> fetchData(int page, int limit) async {
final response = await get(Uri.parse("$baseUrl?page=$page&limit=$limit"));
final data = jsonDecode(response.body);
return Post.fromJson(data).data;
}
class Post {
Post({
required this.status,
required this.message,
required this.length,
required this.page,
required this.limit,
required this.data,
});
final int? status;
final String? message;
final int? length;
final int? page;
final int? limit;
final List<PostData> data;
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
status: json["status"],
message: json["message"],
length: json["length"],
page: json["page"],
limit: json["limit"],
data: json["data"] == null
? []
: List<PostData>.from(json["data"]!.map((x) => PostData.fromJson(x))),
);
}
}
class PostData {
PostData({
required this.id,
required this.content,
});
final String? id;
final String? content;
factory PostData.fromJson(Map<String, dynamic> json) {
return PostData(
id: json["_id"],
content: json["content"],
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment