Home > Blockchain >  Is it possible to enter a null & a List inside of another List?
Is it possible to enter a null & a List inside of another List?

Time:01-08

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");
}
  • Related