Reputation: 41
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
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