sjDev
sjDev

Reputation: 41

Flutter Error - The method isn't defined for the type 'Future' - flutter sqflite database error

I am making an app in a flutter in which I can select the contacts from phone book and need to save them into the flutter local database sqflite. I have separate class for database named database_services.dart. In my other .dart file i m using

var _data = DatabaseService.instance.database;

then after that i m calling

_data.getcontacts() // Error statement

and

data.insertContacts(model)

but it is giving me error below

The method 'insertContacts' isn't defined for the type 'Future'. ry correcting the name to the name of an existing method, or defining a method named 'insertContacts'.

Both .dart files are attached for reference. What should i do ? what is wrong ?

my database class : `

import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';

import 'contact_model.dart';

class DatabaseService{



   DatabaseService._();
  static final DatabaseService instance = DatabaseService._();

   Database? _database;
   String dbName = 'contact.db';
   ContactModel model = ContactModel();


  


     Future<Database?> get database async {

      if(_database!= null){  return _database!;}
      else{
        _database = await initializeDB(dbName);
        return _database!;

      }

    }

   Future<Database> initializeDB(String filePath) async {
      final dbPath = await getDatabasesPath();
      final path = join(dbPath , filePath);

      return await openDatabase(path , version: 1 , onCreate:  _CreateDB ) ;

   }


   Future _CreateDB (Database db , int version) async {
//make like johannes mike at end
      await db.execute(
        'CREATE TABLE contacts (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT,  number TEXT)',


      );

   }


    insertContacts(ContactModel modelObj) async {
     // Get a reference to the database.
     final db = await instance.database;


     //
     await db?.insert(
       dbName,
       modelObj.toMap(),
       conflictAlgorithm: ConflictAlgorithm.replace,
     );
   }




   Future<List<ContactModel>?> getcontacts() async {
     // Get a reference to the database.
     final db = await instance.database;


     var response = await db?.query("contacts");
    


     List<ContactModel>? list = response?.map((c) => ContactModel.fromMap(c)).toList();
     return list;

/*
     return List.generate(maps?.length as int , (i) {
       return ContactModel(
         id: maps![i]['id'] != null ? toString() : ' ',
         displayName: maps[i]['name'] != null ? toString() : ' ',
         phoneNumber: maps[i]['number'] != null ? toString() : ' ',
       );
     });

     */

   }


}
`

my other class:

import 'package:firebase_contacts_test/contact_model.dart';
import 'package:firebase_contacts_test/database_services.dart';
import 'package:flutter/material.dart';
import 'package:fluttercontactpicker/fluttercontactpicker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'contact_model.dart';
import 'package:sqflite/sqflite.dart';

class Plugin1 extends StatefulWidget {
  const Plugin1({Key? key}) : super(key: key);

  @override
  State<Plugin1> createState() => _Plugin1State();
}

class _Plugin1State extends State<Plugin1> {

   var _data =  DatabaseService.instance.database;



  ContactModel model = ContactModel();
  List<ContactModel> _list = [];

  PhoneContact? _contact;

  String? _phoneContact;
  String? _name;
  String? _id;

  final Permission _permission = Permission.contacts;
  PermissionStatus _permissionStatus = PermissionStatus.denied;

  Future<PermissionStatus> _getContactPermission() async {
    _permissionStatus = await _permission.status;

    if (_permissionStatus != PermissionStatus.granted) {
      _permissionStatus = await _permission.request();
      return _permissionStatus;
    } else {
      return _permissionStatus;
    }
  }


   Future<void> printDB() async {

    print('printintgdsfssfdgsdfg  DB');

   if(_data != null) {
     print( await _data.getcontacts());
   }
   else{
     print('no contacts slected');
   }
   }
  pickContact() async {


    PermissionStatus permissionStatus = await _getContactPermission();
    if (permissionStatus == PermissionStatus.granted) {
      final PhoneContact contact =
          await FlutterContactPicker.pickPhoneContact();

      print("my_contact");
      print(contact);

      _phoneContact = contact.phoneNumber?.number;
      _name = contact.fullName;
      _id = '1';
      //set into model
      model = ContactModel( id : _id , displayName: _name, phoneNumber: _phoneContact);

      _data.insertContacts(model);

      _list.add(model);


      setState(()  {

      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            RaisedButton(
              onPressed: () {
                printDB();
              },
              child: Text('show Db contacts'),
            ),
            RaisedButton(
              onPressed: () {
                pickContact();
              },
              child: Text('select contacts'),
            ),
            Expanded(
              child: ListView.builder(
                shrinkWrap: true,
                itemCount: _list.length,
                itemBuilder: (context, position) {
                  return ListTile(
                    leading: Icon(Icons.contacts),
                    title: Text(

                        _list[position].displayName.toString()
                    ),
                    trailing: Icon(Icons.delete));

                },
              ),
            )


            //     Text(_phoneContact ?? "contact not selected" ),
            //    Text(_name ?? "name not selected" ),]
          ],
        ));
  }
}

my contact model class

import 'package:flutter/cupertino.dart';

class ContactModel {
   String?  id = 'id';
   String? displayName = 'name';
   String? phoneNumber = 'number';


  ContactModel({ this.id, this.displayName,  this.phoneNumber});

  //setters
  set contactName(String? dispName) {
    displayName = dispName;
  }

  set contactNumber(String? num)
  {
    phoneNumber = num;
  }

  //getters
   String? get contactName{ return displayName;}
   String? get contactNumber{ return phoneNumber;}


  // Convert a Dog into a Map. The keys must correspond to the names of the
  // columns in the database.
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': displayName,
      'number': phoneNumber,
    };
  }


   factory ContactModel.fromMap(Map<String, dynamic> json) => new ContactModel(
     id: json["id"],
     displayName: json["name"],
     phoneNumber: json["number"],
   );


  // Implement toString to make it easier to see information about
  // each dog when using the print statement.
  @override
  String toString() {
    return 'Dog{id: $id, name: $displayName, age: $phoneNumber}';
  }

}//class ends




   

Upvotes: 2

Views: 3127

Answers (1)

lepsch
lepsch

Reputation: 10379

It should be the following:

await (await _data).getcontacts();

...

await (await _data).insertContacts(model);

This is because _data is an async property and needs an await to get the value out of Future. Also, getcontacts/insertContacts is async and needs another await.

Maybe it'd be nice to get the DB out of _data in another variable like:

final db = await _data;

...

await db.getcontacts();

...

await db.insertContacts(model);

Upvotes: 2

Related Questions