Dealing with asynchronously
Note that the HTTP APIs use Dart Futures in the return values. We recommend using the API calls with the async/await syntax.Create the client.
Construct the Uri.
Invoke the operation, and await the request object. Optionally, configure the headers and body of the request.
Close the request, and await the response.
Decode the response.
Several of these steps use Future based APIs. Sample APIs calls for each step above are:
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'user_model.dart';
class ApiService {
static const String baseUrl = 'https://jsonplaceholder.typicode.com';
/// GET - List of Users
static Future<List<UserModel>> getUsers() async {
final response = await http.get(Uri.parse('$baseUrl/users'));
if (response.statusCode == 200) {
List data = jsonDecode(response.body);
// List<Map> -> List<Model>
return data.map((e) => UserModel.fromJson(e)).toList();
} else {
throw Exception('Failed to load users');
}
}
/// GET - Single User
static Future<UserModel> getUser(int id) async {
final response = await http.get(Uri.parse('$baseUrl/users/$id'));
if (response.statusCode == 200) {
Map<String, dynamic> data = jsonDecode(response.body);
return UserModel.fromJson(data);
} else {
throw Exception('Failed to load user');
}
}
/// POST - Create User
static Future<UserModel> createUser(UserModel user) async {
final response = await http.post(
Uri.parse('$baseUrl/users'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(user.toJson()),
);
if (response.statusCode == 201) {
Map<String, dynamic> data = jsonDecode(response.body);
return UserModel.fromJson(data);
} else {
throw Exception('Failed to create user');
}
}
}
- Model Class (User Model) Example JSON:
class UserModel {
final int id;
final String name;
final String email;
UserModel({
required this.id,
required this.name,
required this.email,
});
// From JSON (Map -> Model)
factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
id: json['id'] ?? 0,
name: json['name'] ?? '',
email: json['email'] ?? '',
);
}
// To JSON (Model -> Map)
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'email': email,
};
}
}
- Simple UI Example main.dart
import 'package:flutter/material.dart';
import 'api_service.dart';
import 'user_model.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: UserScreen(),
);
}
}
class UserScreen extends StatefulWidget {
const UserScreen({super.key});
@override
State<UserScreen> createState() => _UserScreenState();
}
class _UserScreenState extends State<UserScreen> {
List<UserModel> users = [];
bool isLoading = false;
@override
void initState() {
super.initState();
fetchUsers();
}
Future<void> fetchUsers() async {
setState(() => isLoading = true);
try {
users = await ApiService.getUsers();
} catch (e) {
print(e);
}
setState(() => isLoading = false);
}
Future<void> addUser() async {
UserModel newUser = UserModel(
id: 0,
name: "Devik",
email: "devik@test.com",
);
try {
UserModel createdUser = await ApiService.createUser(newUser);
setState(() {
users.add(createdUser);
});
} catch (e) {
print(e);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("API Demo")),
body: isLoading
? const Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index];
return ListTile(
title: Text(user.name),
subtitle: Text(user.email),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: addUser,
child: const Icon(Icons.add),
),
);
}
}
Top comments (0)