Dio MVVM Get API Integration with GetX in Flutter
Learn how to integrate Dio (HTTP client) with MVVM architecture to perform Get API calls efficiently.
Explore sample code, step-by-step tutorial, and best practices for seamless API integration.
dependencies:
flutter:
sdk: flutter
dio: ^5.3.0
get: ^4.6.5
MVVM folder structure
lib/
├── data/
│ ├── models/
│ │ └── user.dart // Contains the User model class for representing user data.
│ ├── repositories/
│ │ └── user_repository.dart // Handles fetching user data from the API.
│ └── services/
│ └── api_service.dart // Provides methods to interact with the API using Dio or other HTTP clients.
│
├── utils/
│ ├── constants.dart // Contains constant values used throughout the app.
│ └── logger.dart // Utility for logging app events or errors.
│
├── view/
│ └── user_list.dart // View file for displaying the list of users.
│
├── view_models/
│ └── user_view_model.dart // ViewModel class for managing user data and API calls.
│
├── widgets/
│ ├── user_tile.dart // Reusable widget for displaying user details in a list.
│ └── loading_spinner.dart // Reusable loading spinner widget.
│
├── main.dart // The main entry point of the Flutter app.
└── locator.dart // File for setting up dependency injection using a service locator pattern.
..
Dio MVVM User List App
Build a Flutter user list app using Dio for API calls and MVVM architecture. Learn how to manage user data and API integration efficiently with sample code and best practices.
main.dart : The main entry point of the Flutter app.
// main.dart
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:flutteryfly/viewmodels/user_view_model.dart';
import 'package:get/get.dart';
import './data/repositories/user_repository.dart';
import './data/services/api_service.dart';
import './views/user_list.dart';
void main() {
// Initialize GetX dependency injection
Get.put(ApiService(dio: Dio())); // ApiService instance
Get.put(UserRepository()); // UserRepository instance
Get.put(UserViewModel()); // UserViewModel instance
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'User List', // Meta Title for the App
theme: ThemeData(
primarySwatch: Colors.green,
),
home: const UserList(),
);
}
}
..
user_list.dart : View file for displaying the list of users.
// views/user_list.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart'; // Import the getx package.
import '../viewmodels/user_view_model.dart';
class UserList extends StatelessWidget {
const UserList({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Users'),
),
body: GetBuilder<UserViewModel>( // Use GetBuilder to access the UserViewModel.
init: UserViewModel(), // Initialize the UserViewModel instance.
builder: (userViewModel) {
// Use the userViewModel to access the state data.
return userViewModel.loading
? const Center(
child: CircularProgressIndicator(),
)
: userViewModel.errorMessage.isNotEmpty
? Center(
child: Text(userViewModel.errorMessage),
)
: ListView.builder(
itemCount: userViewModel.users.length,
itemBuilder: (context, index) {
final user = userViewModel.users[index];
return ListTile(
title: Text(user.name),
subtitle: Text(user.email),
leading: CircleAvatar(
child: Text(user.id.toString()),
),
);
},
);
},
),
);
}
}
..
user_view_model.dart : ViewModel class for managing user data and API calls.
// view_models/user_view_model.dart
import 'package:get/get.dart';
import '../data/models/user.dart';
import '../data/repositories/user_repository.dart';
class UserViewModel extends GetxController {
final UserRepository _userRepository =
Get.find(); // Use GetX's Get.find() to get the UserRepository instance.
final RxList<User> _users =
<User>[].obs; // List to store user data fetched from the API.
bool _loading =
false; // Boolean flag to track if data is currently being fetched.
String _errorMessage =
''; // String to store any error message that occurs during data fetching.
List<User> get users => _users; // Getter method to access the list of users.
bool get loading => _loading; // Getter method to access the loading flag.
String get errorMessage =>
_errorMessage; // Getter method to access the error message.
@override
void onInit() {
super.onInit();
fetchUsers();
}
Future<void> fetchUsers() async {
_loading = true;
_errorMessage = '';
try {
_users.value = await _userRepository.getUsers();
} catch (e) {
_errorMessage = 'Failed to fetch users';
} finally {
_loading = false;
update(); // Use GetX's update() to notify listeners of data change.
}
}
}
..
user_repository.dart : Handles fetching user data from the API.
// data/repositories/user_repository.dart
import 'package:get/get.dart';
import '../models/user.dart';
import '../services/api_service.dart';
class UserRepository {
final ApiService _apiService =
Get.find(); // Use GetX's Get.find() to get the ApiService instance.
Future<List<User>> getUsers() async {
try {
final data = await _apiService.getUsers();
// Map the API response data to a List of User objects using the User.fromJson() constructor.
return data.map((json) => User.fromJson(json)).toList();
} catch (e) {
throw Exception('Failed to fetch users');
}
}
}
..
api_service.dart : Provides methods to interact with the API using Dio or other HTTP clients.
// data/services/api_service.dart
import 'package:dio/dio.dart';
class ApiService {
final Dio _dio; // Dio instance to perform HTTP requests.
ApiService({required Dio dio}) : _dio = dio;
Future<List<dynamic>> getUsers() async {
try {
// Make a GET request to the API endpoint to fetch user data.
final response =
await _dio.get('https://jsonplaceholder.typicode.com/users');
// Check if the response status code is 200 (OK).
if (response.statusCode == 200) {
return response
.data; // If successful, return the response data (List of dynamic).
} else {
// If the response status code is not 200, throw an exception with an error message.
throw Exception('API failed with status code: ${response.statusCode}');
}
} catch (e) {
// If any exception occurs during the API call, throw an exception with the error message.
throw Exception('An error occurred: $e');
}
}
}
..
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "Shanna@melissa.tv",
"address": {
"street": "Victor Plains",
"suite": "Suite 879",
"city": "Wisokyburgh",
"zipcode": "90566-7771",
"geo": {
"lat": "-43.9509",
"lng": "-34.4618"
}
},
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"company": {
"name": "Deckow-Crist",
"catchPhrase": "Proactive didactic contingency",
"bs": "synergize scalable supply-chains"
}
},
]
can you tell me how to create post request using dio mvvm
ReplyDelete