callApiRequest<T> method

Future<ApiResult<T>> callApiRequest<T>({
  1. required Future<Response> request(),
  2. required T parseData(
    1. dynamic data
    ),
  3. Duration? timeout,
})

A centralized wrapper for executing API requests and returning a standardized ApiResult.

This function simplifies API calls by handling try-catch logic, status code validation, and data parsing in one place. It is designed to work seamlessly with the ApiResult class.

The generic type <T> represents the type of the data object that will be parsed and returned on a successful request.

To fetch a single user and parse it into a User object, you would first create a repository function like this:

Future<ApiResult<User>> fetchUser(int userId) async {
  return callApiRequest<User>(
    request: () => _dio.get('/users/$userId'),
    parseData: (json) => User.fromJson(json),
  );
}

Then, you can use the function and handle the result cleanly:

void getUserData() async {
  final result = await fetchUser(1);

  if (result.isSuccess) {
    print('User fetched: ${result.data?.name}');
  } else {
    print('Error fetching user: ${result.message}');
  }
}

Parameters:

  • request: A function that executes the Dio request and returns a Future<Response>. This allows the callApiRequest method to control the execution within its try-catch block.
  • parseData: A function that takes the raw response data (typically dynamic JSON) and returns a strongly-typed object of type T. This is your data model's fromJson factory or a custom parsing logic.

Returns:

  • A Future<ApiResult<T>>. On success (status code 200-299), it completes with an ApiResult where isSuccess is true and the data property holds the parsed object. On any other status code or network exception, it completes with an ApiResult where isFailure is true and the message property contains the error details.

Implementation

Future<ApiResult<T>> callApiRequest<T>(
    {required Future<Response> Function() request,
    required T Function(dynamic data) parseData,
    Duration? timeout}) async {
  try {
    final response =
        timeout != null ? await request().timeout(timeout) : await request();
    return _processResponse(response, decoder: parseData);
  } on DioException catch (e) {
    return _handleDioError(e);
  }
}