a-marenkov/gsheets

Show a List with FutureBuilder never load all

Closed this issue · 4 comments

I create a little app what is show me a list with products saved in Google Sheet, and I do with FutureBuilder but never ends loading the widget even when my list is already load

import 'package:flutter/material.dart';
import 'package:gsheets/gsheets.dart';
import 'package:stock3/producto.dart';

const _credentials= {
"type": "service_account",
"project_id": ,
"private_key_id": ,
"private_key": ,
"client_email": ,
"client_id": ,
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gsheets%40stock-279217.iam.gserviceaccount.com"
};

const _spreadsheetId= '';

class ExcelFunciones {

Future<List> getAllProductos() async {
final gsheets= GSheets(_credentials);
final ss= await gsheets.spreadsheet(_spreadsheetId);
final sheet= ss.worksheetByTitle("inventario");
var list= List();
var aux= Producto();
int fila= 2;
do {
aux.nombre= obtenerDatoExcel((await sheet.cells.cell(row: fila, column: 1)).toString());
if (aux.nombre != "") {
aux.cantidad= int.parse(obtenerDatoExcel((await sheet.cells.cell(row: fila, column: 3)).toString()));
aux.precio= double.parse(obtenerDatoExcel((await sheet.cells.cell(row: fila, column: 2)).toString()));
print("nombre: ${aux.nombre}, cantidad: ${aux.cantidad}, precio: ${aux.precio}");
list.add(aux);
}
fila++;
} while (aux.nombre != "");
print("finlista");
return list;
}

obtenerDatoExcel (String frase) {
int i;
for (i= 1; i < frase.length; i++) {
if (frase[i] == "'") {
frase= frase.substring(1,i);
}
}
return frase;
}

}

import 'package:flutter/material.dart';
import 'package:stock3/navegacion.dart';
import 'package:stock3/funcionesExcel.dart';
import 'package:gsheets/gsheets.dart';
import 'package:stock3/producto.dart';

class VerProductos extends StatefulWidget {
@OverRide
_VerProductosState createState() => _VerProductosState();
}

class _VerProductosState extends State {

List productos;

Future<List> obtenerProductos (productos) async {
productos= await ExcelFunciones().getAllProductos();
return productos;
}

@OverRide
void initState(){
obtenerProductos(productos);
super.initState();
}

@OverRide
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Lista de productos")),
drawer: BarNavegacion(),
body: SafeArea(child: Container(
decoration: BoxDecoration(color: Colors.grey[100]),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
FutureBuilder(
builder: (BuildContext context, AsyncSnapshot <List> snapshot){
print("snap: ${snapshot.data}");
if (!snapshot.hasData || snapshot.connectionState == ConnectionState.done) {
print("snap2: ${snapshot.data}");
return Container(
height: 400,
width: 200,
child:
CircularProgressIndicator()
);
} else {
return ListView.builder(
padding: EdgeInsets.all(10),
itemCount: 3,
itemBuilder: (BuildContext context, int index) {
if (index == 0) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
side: BorderSide(color: Colors.lightGreen[200])
),
color: Colors.lightGreen[400],
elevation: 10,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(10),
child: Card(
color: Colors.yellow[300],
elevation: 15,
child: TextField(
style: TextStyle(
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
fontSize: 25,
color: Colors.black45
),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Buscar producto",
labelStyle: TextStyle(color: Colors.black54)
),
onChanged: (text) {
text= text.toLowerCase();
//Aqui se pone la lista en el cual se realizara la busqueda
setState(() {

                                  });
                                },
                              ),
                            ),
                          )
                        ]
                      ),

                    );
                  } else {
                    return Card(child: Padding(
                      padding: EdgeInsets.all(10),
                      child: Column(
                        children: <Widget>[
                          Text(
                            "Producto",
                            style: TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.bold
                            )
                          ),
                        ],
                      )
                    ));
                  }
                }
              );
            }
          },
        ),
      ]
    ))
  )
);

}
}

@Zorro-cristal Hi! Did you figure out the way to solve it?

Not, I can't resolve this yet

Not, I can't resolve this yet

Hi, i recommend you to read this article

I've spoted a few problems with your code.

  • double.parse and int.parse can throw - always wrap it in try/catch and log;
  • avoid calling gsheets methods for separate cells if you can get data all at once;
  • if you only need value, retrieve value, not the cell object

Hope it helps!


class ExcelFunciones {
  Future<List<Producto>> getAllProductos() async {
    try {
      final gsheets = GSheets(_credentials);
      final ss = await gsheets.spreadsheet(_spreadsheetId);
      final sheet = ss.worksheetByTitle("inventario");

      final rows = await sheet.values.allRows(fromRow: 2, length: 3);

      return rows
          .map<Producto>((row) => Producto(
                nombre: row[0],
                precio: double.parse(row[1]),
                nombre: int.parse(row[2]),
              ))
          .toList();
    } catch (e, s) {
      print(e);
      print(s);
      return <Producto>[];
    }
  }
}

class VerProductos extends StatefulWidget {
  @override
  _VerProductosState createState() => _VerProductosState();
}

class _VerProductosState extends State {
  Future<List<Producto>> productos;
  
  @override
  void initState() {
    super.initState();
    productos = ExcelFunciones().getAllProductos();
  }

/// the rest of the widget

}

Thanks, i can resolve that but now i have a strange problem, when i save the date in array them the date is alterate

var aux= Producto();
List<Producto> lista= List<Producto> ();
int fila= 2;
do {
  aux.nombre= obtenerDatoExcel((await sheet.cells.cell(row: fila, column: 2)).toString());
  if (aux.nombre != "") {
    aux.cantidad= int.parse(obtenerDatoExcel((await sheet.cells.cell(row: fila, column: 4)).toString()));
    aux.precio= double.parse(obtenerDatoExcel((await sheet.cells.cell(row: fila, column: 3)).toString()));
    aux.nombre= aux.nombre.toString();
    aux.codigo= int.parse(obtenerDatoExcel((await sheet.cells.cell(row: fila, column: 1)).toString()));
    aux.descripcion= obtenerDatoExcel((await sheet.cells.cell(row: fila, column: 5)).toString());
    aux.nombreAux= aux.nombre;
    print("codigo: ${aux.codigo}, nombre: ${aux.nombre}, cantidad: ${aux.cantidad}, precio: ${aux.precio}, descripcion: ${aux.descripcion}, nombreAux: ${aux.nombreAux}");
    lista.add(aux);
  }
  fila++;
} while (aux.nombre != "");
//print("fin lista de tam= ${list.length} y nombre= ${list[2].nombre}");
for (int i= 0; i < lista.length; i++) {
  print("elemento [$i]: ${lista[i].codigo}, ${lista[i].nombre}, ${lista[i].precio}, ${lista[i].cantidad}, ${lista[i].descripcion}, ${lista[i].nombreAux}");
}
return lista;

The output is:
I/flutter (20318): codigo: 1, nombre: algo, cantidad: 25, precio: 15000.0, descripcion: algo es algo, nombreAux: algo
I/flutter (20318): codigo: 2, nombre: util, cantidad: 12, precio: 8000.0, descripcion: utilidad nula, nombreAux: util
I/flutter (20318): codigo: 3, nombre: pruebas, cantidad: 15, precio: 12000.0, descripcion: porque lo que no anda?, nombreAux: pruebas
I/flutter (20318): codigo: 4, nombre: funciona, cantidad: 100, precio: 20000.0, descripcion: porque lo que no funciona, nombreAux: funciona
I/flutter (20318): elemento [0]: 4, , 20000.0, 100, porque lo que no funciona, funciona
I/flutter (20318): elemento [1]: 4, , 20000.0, 100, porque lo que no funciona, funciona
I/flutter (20318): elemento [2]: 4, , 20000.0, 100, porque lo que no funciona, funciona
I/flutter (20318): elemento [3]: 4, , 20000.0, 100, porque lo que no funciona, funciona