Ở bài trước, chúng ta đã học cách tạo model và chuyển đổi dữ liệu từ JSON. Hôm nay, mình quyết định gọi API thật để lấy dữ liệu về và hiển thị nó lên UI
Mục tiêu bài học
- Cài package
http
để gọi API - Gọi API REST trả về danh sách JSON
- Parse dữ liệu về model
- Hiển thị dữ liệu bằng
FutureBuilder
1. Cài đặt package http
Để có thể gọi API, chúng ta cần thêm package http
vào dự án. Mở file pubspec.yaml
và thêm dòng sau vào phần dependencies
:
dependencies: http: ^1.4.0
Sau đó, chạy lệnh sau trong terminal để tải package:
flutter pub get
2. Tạo model đơn giản
Hôm nay chúng ta sẽ sử dụng API example sau nhé https://jsonplaceholder.typicode.com/users. Trong API này dữ liệu JSON có dạng như sau:
{ "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" } }
Tuy nhiên hôm nay mình sẽ chỉ sử dụng các thuộc tính cơ bản như id, name, email thôi nhé. Bây giờ chúng ta sẽ bắt đầu xây dựng Model User như sau:
class User { final int id; final String name; final String email; User({required this.id, required this.name, required this.email}); factory User.fromJson(Map<String, dynamic> json) { return User( id: json['id'], name: json['name'], email: json['email'], ); }
}
3. Gọi API với http.get
Tiếp theo, chúng ta sẽ tạo một hàm bất đồng bộ để thực hiện yêu cầu HTTP và lấy dữ liệu người dùng. Hãy đặt hàm này trong một file riêng hoặc cùng với model User
nếu bạn muốn.
import 'package:http/http.dart' as http;
import 'dart:convert';
// Đảm bảo bạn đã định nghĩa class User ở đây hoặc import từ file khác
// import 'user.dart'; Future<List<User>> fetchUsers() async { final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users')); if (response.statusCode == 200) { // Nếu server trả về mã trạng thái 200 OK, parse JSON List jsonData = json.decode(response.body); // Chuyển đổi List JSON thành List các đối tượng User return jsonData.map((e) => User.fromJson(e)).toList(); } else { // Nếu server không trả về mã 200 OK, ném ra một ngoại lệ throw Exception('Failed to load users'); }
}
4. Hiển thị với FutureBuilder
Bây giờ chúng ta sẽ dùng FutureBuilder để gọi fetchUsers() và hiển thị kết quả:
import 'package:flutter/material.dart';
// Đảm bảo import file chứa hàm fetchUsers() và class User
// import 'user_service.dart';
// import 'user.dart'; class UserListScreen extends StatelessWidget { const UserListScreen({super.key}); Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Danh sách người dùng')), body: FutureBuilder<List<User>>( future: fetchUsers(), // Hàm fetchUsers() sẽ được gọi builder: (context, snapshot) { // Trạng thái chờ dữ liệu if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // Trạng thái có lỗi else if (snapshot.hasError) { return Center(child: Text('Lỗi: ${snapshot.error}')); } // Trạng thái không có dữ liệu hoặc dữ liệu rỗng else if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center(child: Text('Không có dữ liệu')); } // Trạng thái có dữ liệu, hiển thị danh sách final users = snapshot.data!; return ListView.builder( itemCount: users.length, itemBuilder: (context, index) { final user = users[index]; return ListTile( leading: CircleAvatar(child: Text(user.id.toString())), title: Text(user.name), subtitle: Text(user.email), ); }, ); }, ), ); }
}
Và đây là kết quả của chúng ta 🤣🤣🤣
Kết luận
Qua bài học này, bạn đã nắm được cách thực hiện một yêu cầu HTTP để lấy dữ liệu từ API, parse dữ liệu JSON thành các đối tượng Dart, và hiển thị chúng một cách hiệu quả trên giao diện người dùng bằng FutureBuilder
. Đây là một kỹ năng nền tảng quan trọng cho mọi ứng dụng Flutter cần tương tác với dữ liệu từ xa.
Hẹn gặp lại các bạn ở bài viết tiếp theo nhé. Nếu bài viết có vấn đề gì hoặc các bạn có góp ý gì thì hãy cmt ở dưới giúp mình nhé.