Currently I have a service that fetches posts from an API:
Future<List<Post>> fetchPosts(int? limit, int? page) async {
final http.Response response = await http.get(Uri.parse('$BACKEND_URL/posts?page=$page&limit=$limit'));
if (response.statusCode == 200) {
List body = jsonDecode(response.body);
List<Post> posts = body.map((var post) => Post.fromJson(post)).toList();
return posts;
}
return [];
}
Currently, when the statusCode
is NOT 200, it just returns an empty List.
But when it came to error handling, I thought of returning the List of posts inside another List with an error item:
Looks something like this:
return [data, error];
So if the posts are fetched successfully, it should return:
return [[Post(), Post(), Post()], null];
And if it causes an error, it should return:
return [null, "Failed to get posts"];
I tried a lot of solutions, like changing the method's return type to Future<dynamic>
.
But is there a way to type the values for return the two items?
Something like:
Future<List<List<Post>?, String?>> fetchPosts(int? limit, int? page) async {}
Can anyone help?
CodePudding user response:
There are much better ways to handle errors in dart.
Solution #1
Create a class FetchPostsResponse
with two properties for message and list of posts. Then change your function to return this class.
class FetchPostsResponse {
final List<Post>? posts;
final String? message;
FetchPostsResponse({
this.posts,
this.message,
});
}
Future<FetchPostsResponse> fetchPosts(int? limit, int? page) async {
final http.Response response =
await http.get(Uri.parse('$BACKEND_URL/posts?page=$page&limit=$limit'));
if (response.statusCode == 200) {
List body = jsonDecode(response.body);
List<Post> posts = body.map((var post) => Post.fromJson(post)).toList();
return FetchPostsResponse(posts: posts);
}
return FetchPostsResponse(message: "Failed to get posts");
}
Solution #2 more maintainable and extensible.
Create an abstract class FetchPostsState
and create a new class that extends the abstract class for each state, such as success and failure.
abstract class FetchPostsState {}
class FetchPostsSuccess extends FetchPostsState {
final List<Post> data;
FetchPostsSuccess(this.data);
}
class FetchPostsFail extends FetchPostsState {
final String message;
FetchPostsFail(this.message);
}
Future<FetchPostsState> fetchPosts(int? limit, int? page) async {
final http.Response response = await http.get(Uri.parse('$BACKEND_URL/posts?page=$page&limit=$limit'));
if (response.statusCode == 200) {
List body = jsonDecode(response.body);
List<Post> posts = body.map((var post) => Post.fromJson(post)).toList();
return FetchPostsSuccess(posts);
}
return FetchPostsFail("Failed to get posts");
}