Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Dúvida sobre como acessar o ID criado pelo sqflite

Olá estou tentando fazer meu próprio CRUD com sqflite e fiquei preso em um problema com as funções delete e update que necessitam do id. Quis deixar para o próprio sqflite gerar o id então o meu Card (que foi utilizado para gerar a lista) ficou assim:

class TestListItem extends StatefulWidget {
  final String task;
  final String date;
  final int? taskId;

  const TestListItem(
      {Key? key, required this.task, required this.date, this.taskId})
      : super(key: key);

 ...

          CheckboxListTile(
              controlAffinity: ListTileControlAffinity.leading,
              secondary:
              IntrinsicWidth(
                child: Row(
                  children: [
                    IconButton(onPressed: (){
                      Navigator.pushNamed(context, "form").then((value) => setState((){}));
                    }, icon: Icon(Icons.edit),),
                    IconButton(onPressed: (){
                      TaskDao().delete(widget.taskId); // aqui ocorre o problema de não reconhecer o id que será criado pelo banco de dados.
                    }, icon: Icon(Icons.delete), color: Colors.redAccent),
                  ],
                ),
              ),
              title: Text(
                widget.task,
                style: TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                ),
              ),
              subtitle: Text(
                widget.date,
                style: TextStyle(
                  color: Colors.blue,
                  fontWeight: FontWeight.bold,
                ),
              ),
        ...
}

Entretanto, na hora de realizar o delete no ícone da lista o processo não é realizado pois retorna o id como null e impede o build do aplicativo e mesmo se colocar para receber um id nullável o resultado ao clicar no ícone de deletar é que o id é nulo e o card não some, nem é deletado do banco de dados.

class TaskDao {
  // Criar primeiro para depois criar o database.
  static const String _tablename = "taskTable";
  static const String _taskid = "taskID";
  static const String _task = "task";
  static const String _date = "date";

  static const String tableSql = "CREATE TABLE $_tablename("
      "$_taskid INTEGER PRIMARY KEY, "
      "$_task TEXT, "
      "$_date TEXT)";

  Map <String, dynamic> toMap(TestListItem testListItem) {
    print("Convertendo Task em Map: ");
    final Map<String,
        dynamic> taskMap = Map(); 
    taskMap[_task] = testListItem.task;
    taskMap[_date] = testListItem.date;
    print("Mapa de tasks $taskMap");
    return taskMap;
  }

  List<TestListItem> toList(List<Map<String, dynamic>> taskMap) {
    print("Convertendo to List:");
    //Deve criar uma função que recebe o mapa e transforma em lista vazia.
    final List <TestListItem> taskList = []; 
    print("Task List vazia $taskList");
    for (Map<String, dynamic> line in taskMap) {
      final TestListItem task = TestListItem(
        taskId: line[_taskid],
        task: line[_task],
        date: line[_date],
      );
      taskList.add(task); 
    }
    print(" Lista de Tarefas preenchida $taskList. ");
    return taskList; 
  }

  save (TestListItem task) async{
    print("Iniciando o save: ");
    final Database database = await getDataBase();
    final itemExists = await find(task.taskId); 
    Map<String,dynamic> taskMap = toMap(task); 
    if(itemExists.isEmpty) { //Se não existir o insere no database.
      print ("A tarefa não existia.");
      return await database.insert(_tablename, taskMap); 
    }

    delete(int? taskId) async{
    print("Deletando tarefa: $taskId");
    final Database database = await getDataBase();
    return database.delete(_tablename, where: "$_taskid = ?", whereArgs: [taskId]);
  }

Queria entender uma forma de passar o id que será criado no banco de dados para o int? id do TestListItem para poder realizar o delete.

Aqui é onde se realiza o save no banco de dados:

floatingActionButton: FloatingActionButton.extended(
          onPressed: () {
            if (_formKey.currentState!.validate()) {
              TaskDao().save(TestListItem(
                  task: taskController.text, date: dateController.text),);
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(
                  behavior: SnackBarBehavior.floating,
                  margin: EdgeInsets.all(8),
                  content: Text("Tarefa inserida com sucesso",),
                ),
              );

              Navigator.pop(context);
            }
          },
4 respostas

Fala Gabriel, de boa ?

Cara consegue mostrar pra gente o código completo do TaskDao ? Acho que o problema esteja lá.

solução!

Olá, Matheus tudo certo.

Então eu acabei resolvendo de outra forma, ao invés de utilizar o id criado pelo sqflite eu coloquei o taskId como required e utilizei a chave gerada pelo Uuid como taskId assim conseguia atrelá-lo ao Card da lista para exclusão e alteração. Não tenho mais o código original dessa questão, mas o TaskDao está completo aqui (para a parte que interessa ao questionamento, o restante do código era somente o método de findAll do CRUD):

class TaskDao {
  // Criar primeiro para depois criar o database.
  static const String _tablename = "taskTable";
  static const String _taskid = "taskID";
  static const String _task = "task";
  static const String _date = "date";

  static const String tableSql = "CREATE TABLE $_tablename("
      "$_taskid INTEGER PRIMARY KEY, "
      "$_task TEXT, "
      "$_date TEXT)";

  Map <String, dynamic> toMap(TestListItem testListItem) {
    print("Convertendo Task em Map: ");
    final Map<String,
        dynamic> taskMap = Map(); 
    taskMap[_task] = testListItem.task;
    taskMap[_date] = testListItem.date;
    print("Mapa de tasks $taskMap");
    return taskMap;
  }

  List<TestListItem> toList(List<Map<String, dynamic>> taskMap) {
    print("Convertendo to List:");
    //Deve criar uma função que recebe o mapa e transforma em lista vazia.
    final List <TestListItem> taskList = []; 
    print("Task List vazia $taskList");
    for (Map<String, dynamic> line in taskMap) {
      final TestListItem task = TestListItem(
        taskId: line[_taskid],
        task: line[_task],
        date: line[_date],
      );
      taskList.add(task); 
    }
    print(" Lista de Tarefas preenchida $taskList. ");
    return taskList; 
  }

  save (TestListItem task) async{
    print("Iniciando o save: ");
    final Database database = await getDataBase();
    final itemExists = await find(task.taskId); 
    Map<String,dynamic> taskMap = toMap(task); 
    if(itemExists.isEmpty) { //Se não existir o insere no database.
      print ("A tarefa não existia.");
      return await database.insert(_tablename, taskMap); 
    }

    delete(int? taskId) async{
    print("Deletando tarefa: $taskId");
    final Database database = await getDataBase();
    return database.delete(_tablename, where: "$_taskid = ?", whereArgs: [taskId]);
  }

O lance era ver o findAll mesmo kkk

Acho que tu não tava recuperando o id nele, mas se tu conseguiu contornar a situação, ótimo tb :)

Consegui achar algo nos commits antigos:

Future<List<TestListItem>> findAll() async{
    print("Acessando o findAll: ");
    final Database database = await getDataBase(); //Instância do banco de dados.
    final List<Map<String,dynamic>> result = await database.query(_tablename); //Cria uma lista de mapas de todos os dados do database.
    print("Procurando dados no banco de dados ... encontrado: $result");
    return toList(result); // Transforma tudo em lista de tasks para exibir na tela.
  }

Mas o id já tinha sido recuperado no toList aqui do código anterior não?

List<TestListItem> toList(List<Map<String, dynamic>> taskMap) {
    print("Convertendo to List:");
    //Deve criar uma função que recebe o mapa e transforma em lista vazia.
    final List <TestListItem> taskList = []; 
    print("Task List vazia $taskList");
    for (Map<String, dynamic> line in taskMap) {
      final TestListItem task = TestListItem(
        taskId: line[_taskid],
        task: line[_task],
        date: line[_date],
      );
      taskList.add(task); 
    }
    print(" Lista de Tarefas preenchida $taskList. ");
    return taskList; 
  }