Antes de gestionar el estado de una aplicación Flutter con Provider, es fundamental entender cómo estructurar los datos. Un modelo de datos define los atributos que un conjunto de información debe tener, y construirlo correctamente facilita el manejo, la conversión y la refactorización de esa información a lo largo de todo el proyecto.
¿Cómo se estructura un modelo de receta en Dart?
Dentro de la carpeta lib del proyecto, se crea una nueva carpeta llamada models para almacenar todos los modelos. En este caso, el archivo se denomina recipe_model.dart [00:18].
El modelo se define como una clase llamada Recetas, que contiene los tipos de datos necesarios:
name: de tipo String, representa el nombre de la receta.
author: de tipo String, indica el autor.
imageLink: de tipo String, almacena el enlace de la imagen.
recipeSteps: de tipo List<String>, contiene el paso a paso de la receta.
Después de declarar las propiedades, se construye un constructor donde cada parámetro se marca como required [01:20]. Esto garantiza que al instanciar la clase, toda la información sea obligatoria para poder mostrar las recetas correctamente.
¿Qué es un factory y por qué usar fromJson?
Un factory constructor permite tener un mejor manejo y cambio de estado de la clase [01:48]. Se conecta con el método fromJson, que recibe un Map<String, dynamic> y realiza un mapeo de cada elemento que viene del JSON.
Dentro de este factory, se retorna una nueva instancia de la clase asignando cada campo según su ubicación en el JSON:
dart
factory Recetas.fromJson(Map<String, dynamic> json) {
return Recetas(
name: json['name'],
author: json['author'],
imageLink: json['image_link'],
recipeSteps: List<String>.from(json['recipes']),
);
}
El campo recipeSteps, al ser un listado, necesita indicar explícitamente que es una List<String> y se extrae con List<String>.from() [02:48].
¿Cómo funciona el método toJson?
El método toJson es el conversor inverso: transforma la instancia del modelo en un Map<String, dynamic> para poder enviarlo o almacenarlo como JSON [03:18].
dart
Map<String, dynamic> toJson() {
return {
'name': name,
'author': author,
'image_link': imageLink,
'recipes': recipeSteps,
};
}
Cada propiedad se iguala a su variable correspondiente, lo que permite reconstruir el JSON de forma limpia.
¿Para qué sirve el override de toString?
Aunque no es obligatorio, agregar un override del método toString resulta muy útil durante el proceso de debugging [03:55]. Este método convierte toda la información del modelo en una cadena de texto visible en la consola.
Para incluir variables dentro de un string en Dart, se utiliza el símbolo $ seguido del nombre de la variable, lo que se conoce como interpolación de strings [04:22]:
dart
@override
String toString() {
return 'name: $name, author: $author, imageLink: $imageLink, recipeSteps: $recipeSteps';
}
Esto permite visualizar rápidamente los datos de cualquier instancia al imprimirla.
¿Por qué un modelo es clave antes de usar Provider?
Un modelo actúa como el esquema que define qué información necesita cada entidad de la aplicación [05:08]. En este ejemplo, una receta requiere nombre, autor, imagen y pasos. Tener esta estructura clara permite:
- Refactorizar los datos de forma ordenada.
- Facilitar la creación del Provider para la gestión de estado.
- Convertir datos entre objetos Dart y JSON de manera bidireccional con
fromJson y toJson.
Si ya has trabajado con modelos en otros lenguajes, notarás que el patrón es muy similar. ¿Qué otros atributos agregarías a este modelo de receta? Comparte tu enfoque en los comentarios.