Este servicio consulta el backend Node/Express + MongoDB. Empecemos por el GET, que trae la lista completa:
dart🔒
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../models/product.dart';
import 'api_config.dart';
class ProductService {
// GET: Obtener todos los productos
static Future<List<Product>> getProductos() async {
final response = await http.get(
Uri.parse('${ApiConfig.baseUrl}/productos'),
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0',
},
);
if (response.statusCode == 200) {
List<dynamic> body = jsonDecode(response.body);
return body.map((item) => Product.fromJson(item)).toList();
} else {
throw Exception('Error al cargar productos (Código: ${response.statusCode})');
}
}
Ahora las operaciones para crear y actualizar un producto, dentro de la misma clase (usan los mismos nombres de campo que ya viste en el mapeo: Nombre, Descripcion, Precio, Image):
dart🔒
// POST: Crear un nuevo producto
static Future<Product> crearProducto({
required String nombre,
required String descripcion,
required double precio,
required String image,
}) async {
final response = await http.post(
Uri.parse('${ApiConfig.baseUrl}/productos'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'Nombre': nombre,
'Descripcion': descripcion,
'Precio': precio,
'Image': image,
}),
);
if (response.statusCode == 200 || response.statusCode == 201) {
return Product.fromJson(jsonDecode(response.body));
} else {
throw Exception('Error al crear el producto (Código: ${response.statusCode})');
}
}
// PUT: Actualizar un producto existente
static Future<Product> actualizarProducto({
required String productId,
required String nombre,
required String descripcion,
required double precio,
required String image,
}) async {
final response = await http.put(
Uri.parse('${ApiConfig.baseUrl}/productos/$productId'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'Nombre': nombre,
'Descripcion': descripcion,
'Precio': precio,
'Image': image,
}),
);
if (response.statusCode == 200) {
return Product.fromJson(jsonDecode(response.body));
} else {
throw Exception('Error al actualizar el producto (Código: ${response.statusCode})');
}
}
Y para cerrar la clase, eliminar un producto:
dart🔒
// DELETE: Eliminar un producto
static Future<void> eliminarProducto(String productId) async {
final response = await http.delete(
Uri.parse('${ApiConfig.baseUrl}/productos/$productId'),
);
if (response.statusCode != 200 && response.statusCode != 204) {
throw Exception('Error al eliminar el producto (Código: ${response.statusCode})');
}
}
}
🧪 Prueba este paso
Con el backend Node/Express y MongoDB corriendo, llama ProductService.getProductos() desde un FutureBuilder simple en main.dart y revisa que no aparezca ninguna excepción en consola. Si el backend aún no está listo, confirma que el estado de error se muestre controlado (sin cerrar la app). Las operaciones crearProducto, actualizarProducto y eliminarProducto las probarás más adelante, cuando construyas las pantallas que las usan (por ejemplo, un panel de administración de productos).