I have a model class ProductoModelo
import 'dart:convert';
List<ProductoModelo> productoModeloFromJson(String str) =>
List<ProductoModelo>.from(
json.decode(str).map((x) => ProductoModelo.fromJson(x)));
String productoModeloToJson(List<ProductoModelo> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class ProductoModelo {
ProductoModelo({
required this.id,
required this.sku,
required this.nombre,
required this.descripcion,
required this.destacado,
required this.visible_en_tienda,
required this.imagen,
required this.categoria,
required this.sub_cat,
required this.sub_cat2,
required this.sub_cat3,
});
String id;
String sku;
String nombre;
String descripcion;
String destacado;
String visible_en_tienda;
String imagen;
String categoria;
String sub_cat;
String? sub_cat2;
String? sub_cat3;
factory ProductoModelo.fromJson(Map<String, dynamic> json) => ProductoModelo(
id: json["id"],
sku: json["sku"],
nombre: json["nombre"],
descripcion: json["descripcion"],
destacado: json["destacado"],
visible_en_tienda: json["visible_en_tienda"],
imagen: json["imagen"],
categoria: json["categoria"],
sub_cat: json["sub_cat"],
sub_cat2: json["sub_cat2"] ?? "",
sub_cat3: json["sub_cat3"] ?? "");
Map<String, dynamic> toJson() => {
"id": id,
"sku": sku,
"nombre": nombre,
"descripcion": descripcion,
"destacado": destacado,
"visible_en_tienda": visible_en_tienda,
"imagen": imagen,
"categoria": categoria,
"sub_cat": sub_cat,
"sub_cat2": sub_cat2,
"sub_cat3": sub_cat3,
};
}
And this is how am I getting the JSON string from API
import 'package:capenergy_ns/modelos/producto_modelo.dart';
import 'package:http/http.dart' as http;
import '../constantes/constantes.dart';
import '../modelos/publicacion_modelo.dart';
Future<List<ProductoModelo>> fetchProductos() async {
String url = Constantes().URLProyecto Constantes().APICarpeta "get_productos.php";
final response = await http.get(Uri.parse(url));
print("RESPONSE BODY productos" response.body.toString());
return productoModeloFromJson(response.body);
}
The problem is that the API is sending some null values for two of the fields: sub_cat2
and sub_cat3
.
Here is an example of API output:
{"id":"120","sku":"853001","nombre":"Flu\u00eddo de rellenado de arrugas","destacado":"0","descripcion":"Flu\u00eddo de rellenado de arrugas. \u00c1cido hialur\u00f3nico. Formato Vial de f\u00e1cil aplicaci\u00f3n monouso. Caja de 10 unidades de 3 ml. [10 aplicaciones]","visible_en_tienda":"1","precio":"47.8","imagen":"fluidoAcidoroll-on.jpg","categoria":"Cremas","sub_cat":"Fluidos","sub_cat2":"Linea Medicina est\u00e9tica","sub_cat3":null}
Due to these null values I am not getting any objects to a ListView.
How can I solve this issue.
EDIT
Here you have the class where I am getting and showing the API items
Expanded(
child: Container(
child: FutureBuilder(
future: fetchProductos(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<dynamic>? filteredList = snapshot.data as List;
print("a minusculas:"
_controller.text.toLowerCase());
filteredList = filteredList
.where((element) => (element.nombre
.toLowerCase()
.contains(
_controller.text.toLowerCase()) ||
element.nombre.toLowerCase().contains(
_controller.text.toLowerCase())))
.toList();
print("texto filtrado="
_controller.text.toLowerCase());
return Padding(
padding: const EdgeInsets.only(bottom: 20),
child: ListView.builder(
itemCount: filteredList.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, index) {
ProductoModelo producto = filteredList![index];
return new GestureDetector(
onTap: () {
},
child: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: new Card(
elevation: 6,
child: Column(
children: [
new Container(
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Container(
height: 80,
width: 80,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(Constantes().URLProductos producto.imagen)
)
),
),
SizedBox(width: 5,),
Column(
children: [
//nombre
Container(
width: MediaQuery.of(context).size.width -120,
height: 60,
child: Padding(
padding:
const EdgeInsets
.all(1.0),
child: Text(
"${producto.nombre}",
maxLines: 2,
style: TextStyle(
fontSize: 16,
fontWeight:
FontWeight
.bold),
),
),
),
//categoria
Container(
width: MediaQuery.of(context).size.width -120,
height: 60,
child: Padding(
padding:
const EdgeInsets
.all(1.0),
child: Text(
"${producto.categoria}",
style: TextStyle(
fontSize: 14,
),
),
),
),
],
),
],
),
],
),
],
),
],
),
),
],
),
),
),
);
},
),
);
}
CodePudding user response:
First change your builder to this:
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
....
}else (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}else {
return SizedBox();
}
then change your fetchProductos
to this:
Future<List<ProductoModelo>> fetchProductos() async {
try {
String url = Constantes().URLProyecto
Constantes().APICarpeta
"get_productos.php";
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
print("RESPONSE BODY productos" response.body.toString());
return productoModeloFromJson(response.body);
}else {
return [];
}
} catch (e) {
print("error = $e");
return [];
}
}
also change your model to this:
factory ProductoModelo.fromJson(Map<String, dynamic> json) => ProductoModelo(
id: json["id"] ?? "",
sku: json["sku"] ?? "",
nombre: json["nombre"] ?? "",
descripcion: json["descripcion"] ?? "",
destacado: json["destacado"] ?? "",
visible_en_tienda: json["visible_en_tienda"] ?? "",
imagen: json["imagen"] ?? "",
categoria: json["categoria"] ?? "",
sub_cat: json["sub_cat"] ?? "",
sub_cat2: json["sub_cat2"] ?? "",
sub_cat3: json["sub_cat3"] ?? "");