Home > Mobile >  ListView not showing any items due to null values
ListView not showing any items due to null values

Time:11-07

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"] ?? "");
  • Related