ccci_utility 1.1.40+17 ccci_utility: ^1.1.40+17 copied to clipboard
A collection of utility classes and templates for building Flutter applications efficiently.
CCCI Utility #
This documentation provides an overview of the CCCI Utils, including custom widgets, utility classes, and network handling.
Table of Contents #
Utility Classes #
BaseApi #
A base class for making API calls using the Dio HTTP client. #
- The [BaseApi] class provides an abstraction for performing standard HTTP operations such as
GET
,POST
,PUT
, andDELETE
. It simplifies the process of interacting with RESTful APIs by using the Dio library, and it handles common tasks such as building routes, sending requests, and error handling.
Usage #
- The class can be used to build specific API services by passing a route and a [DioClient] instance. Each method supports optional parameters to customize requests, such as query parameters or request paths.
- Example of usage:
final userApi = BaseApi('/users', dioClient);
final user = await userApi.getById('123');
Key Concepts #
- Dio: A powerful HTTP client for Dart, which allows easy HTTP requests.
- Error Handling: Errors from the API requests are logged using [AppLogger] and rethrown for further handling in the app layer.
- Customization: Each method allows customization with optional query parameters or paths, making it versatile for various API requests.
Parameters: #
String route
: The base route (or endpoint) for the API service. This is used as the starting point for all HTTP requests.DioClient dioClient
: An instance of the Dio HTTP client used to perform network requests.
Constructor: #
BaseApi(this.route, this.dioClient)
:- Accepts a [route] and a [dioClient] for making requests to the API.
Methods: #
- getById: Sends a
GET
request to fetch a resource by its unique ID. - get: Sends a
GET
request to fetch resources, optionally with query parameters or a specific path. - post: Sends a
POST
request to create a new resource with a payload. - put: Sends a
PUT
request to update an existing resource by its unique ID. - delete: Sends a
DELETE
request to remove a resource by its unique ID.
Example of Extending the Base Class: #
class UserApi extends BaseApi {
UserApi(DioClient dioClient) : super('/users', dioClient);
Future fetchUsers() => get();
}
In this example, the UserApi
class extends [BaseApi] and uses the get
method
to fetch users from the /users
endpoint.
Base Repository #
A generic repository class for handling data retrieval and management from APIs.
The [BaseRepository] class provides an abstraction layer for interacting with APIs, allowing for consistent and reusable CRUD operations on data entities. It is designed to be used with model classes of type [T], and it relies on a [BaseApi] service for making HTTP requests.
This class offers methods to retrieve a list of entities or a single entity by ID, using the provided [BaseApi] for the underlying HTTP operations. It also handles error logging via [AppLogger].
Usage #
- The class is abstract and should be extended by specific repositories for individual data entities. Each repository should define the [fromJson] method, which is responsible for converting JSON responses into model objects.
Example of usage:
class UserRepository extends BaseRepository<User> {
UserRepository(BaseApi api) : super(api, (json) => User.fromJson(json));
}
Key Concepts #
- BaseApi: The service used for making HTTP requests. This class uses [BaseApi] for all API interactions, such as GET, POST, PUT, and DELETE requests.
- Model Conversion: The [fromJson] function is required to convert the JSON data returned by the API into the model objects of type [T].
- Error Handling: Errors are caught and logged using [AppLogger], with the original error rethrown for higher-level handling.
Parameters: #
BaseApi api
: The API service used to perform HTTP requests.T Function(Map<String, dynamic>) fromJson
: A function that converts a JSON map into an instance of the model class [T].
Constructor: #
BaseRepository(this.api, this.fromJson)
:- Accepts an [api] instance and a [fromJson] function to initialize the repository.
Methods: #
- get: Retrieves a list of entities from the API using optional query parameters.
- getById: Retrieves a single entity by its unique identifier, with optional query parameters.
Example of Extending the Base Class: #
class ProductRepository extends BaseRepository<Product> {
ProductRepository(BaseApi api) : super(api, (json) => Product.fromJson(json));
Future<List<Product>> fetchProducts({Map<String, dynamic>? filters}) {
return get(queryParameters: filters);
}
Future<Product> fetchProductById(String id) {
return getById(id);
}
}
In this example, the ProductRepository
extends [BaseRepository] to handle
product-related API calls, such as fetching a list of products or a single product by ID.
Base Service Provider #
An abstract base class for creating service providers using Riverpod.
This class provides the foundation for service providers by accepting a
ProviderRef
in the constructor. It allows access to the provider's
context and resources, and can be extended to create various service
providers.
The ProviderRef
is stored in a private field ref
, allowing derived
classes to access it for various purposes such as managing state,
listening to other providers, or performing dependency injection.
Usage #
To create a service provider, extend this BaseServiceProvider
class
and implement the specific business logic in your custom provider class.
Example:
class AuthServiceProvider extends BaseServiceProvider {
AuthServiceProvider(ProviderRef ref) : super(ref);
void signIn(String email, String password) {
// Logic to handle user sign-in using ref to interact with providers.
}
}
This allows you to centralize logic related to specific functionalities, such as authentication, networking, or data storage, and share this functionality across your application using Riverpod.
Key Concepts #
-
ProviderRef: This is a handle to interact with other providers or manage state within Riverpod. The
ProviderRef
object is essential for accessing other providers and interacting with the global provider system. -
Extendability: The
BaseServiceProvider
can be extended to create specialized service providers. Each derived class will inherit access to theref
field, allowing for dependency injection or interactions with other providers. -
Riverpod: This class is part of a project that uses Riverpod for state management, which offers a declarative way to manage dependencies and app state in Flutter.
Parameters: #
ProviderRef ref
: The reference to the Riverpod provider that this service provider will use for its logic.
Properties: #
ref
: A private field of typeProviderRef
which provides access to other providers within the Riverpod framework.
Constructor: #
BaseServiceProvider(ProviderRef ref)
:- Accepts a
ProviderRef
as a parameter and assigns it to the private fieldref
for future use within the derived service provider.
- Accepts a
Example of Extending the Base Class #
class NetworkServiceProvider extends BaseServiceProvider {
NetworkServiceProvider(ProviderRef ref) : super(ref);
Future<void> fetchData() async {
// Use ref to access other providers or state management.
// Example: final apiService = ref.read(apiServiceProvider);
}
}
In this example, the NetworkServiceProvider
extends the BaseServiceProvider
and uses the ref
to interact with other providers like apiServiceProvider
.
AppLogger #
The AppLogger class is a utility class for logging messages in the application at different levels of severity. It provides static methods for logging debug, info, warning, error, and verbose messages. Additionally, it includes methods for logging API requests, responses, and errors.
Usage: #
AppLogger.debug('Debug message');
AppLogger.error('Error message');
AppLogger.logApiRequest(url: 'https://api.example.com', method: 'GET');
RouteHandler #
The RouteHandler class is a utility class for handling navigation operations within the application. It provides methods for pushing, popping, and replacing routes in the navigator stack. These methods facilitate seamless navigation between different screens and components within the application.
RouteHandler.push(context, HomePage());
RouteHandler.pop(context);
DioExceptions #
The DioExceptions class is a custom exception class that handles errors from Dio requests. It provides custom error messages based on different types of Dio exceptions encountered, including connection timeouts, receive timeouts, bad responses, and unknown errors.
Usage: #
try {
// Dio request
} catch (e) {
if (e is DioException) {
final dioException = DioExceptions.fromDioError(e);
print(dioException.message);
}
}
DioClient #
The DioClient class encapsulates functionality for making HTTP requests using the Dio package. It includes methods for making GET, POST, PUT, and DELETE requests with configurable options and interceptors. This class provides a convenient and efficient way to interact with APIs and handle network requests within the application.
Dart Dependencies #
To use the DioClient, you need to have the following Dart packages in your pubspec.yaml:
dependencies:
dio
flutter_dotenv
Configuration Files #
Make sure you have the necessary configuration files:
-
. env
Usage:
BASE_URL=<your_base_url>
-
config.json
Usage:
{ "development": { "current": true, "baseUrl": "https://dev.example.com" }, "production": { "current": false, "baseUrl": "https://api.example.com" } }