I'm new to flutter and sqflite. For a project I was trying to use an existing database. I have kept my db file in a assest folder. When I run it on my emulator it shows nothing. Can someone tell me where did I do wrong? It's exactly not showing any error, but it's showing something like:
HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1
ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3
ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem
ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2
ANDROID_EMU_YUV420_888_to_NV21 ANDROID_EMU_YUV_Cache
ANDROID_EMU_async_unmap_buffer GL_OES_EGL_image_external_essl3
GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr
ANDROID_EMU_gles_max_version_3_0
W/OpenGLRenderer( 5874): Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..
class DatabaseHelper {
static final _databaseName = "lastRandomdb.db";
static final _databaseVersion = 1;
static final table = "Randomdb";
static final columnEmail = "email";
static final columnName = "name";
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database _database;
Future<Database> get database async {
if (database != null) return database;
_database = await _initDatabase();
return _database;
}
_initDatabase() async {
var databasepath = await getDatabasesPath();
String path = join(databasepath, _databaseName);
//check existing
var exists = await databaseExists(path);
if (!exists) {
print("copy database start");
try {
await Directory(dirname(path)).create(recursive: true);
} catch (_) {
//copy
ByteData data = await rootBundle.load(join("assets", _databaseName));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
//write
await File(path).writeAsBytes(bytes, flush: true);
}
} else {
print("opening exsisting database");
}
return await openDatabase(path, version: _databaseVersion);
}
//crud
Future<List<Contact>> getAllContacts() async {
Database db = await instance.database;
final List<Map<String, dynamic>> map = await db.query(table);
return List.generate(map.length, (index) {
return Contact.fromMap(map[index]);
});
}
Future<int> getCount() async {
Database db = await instance.database;
return Sqflite.firstIntValue(
await db.rawQuery("SELECT COUNT(EMAIL) FROM $table"));
}
}
this is my model file
final String COL_NAME = "name";
final String COL_EMAIL = "email";
class Contact {
String name, email;
Contact({this.name, this.email});
Contact.map(dynamic obj1) {
this.name = obj1['NAME'];
this.email = obj1['EMAIL'];
}
Map<String, dynamic> toMap() {
var map = <String, dynamic>{
//method
COL_NAME: name,
COL_EMAIL: email,
};
return map;
}
Contact.fromMap(Map<String, dynamic> map) {
//named constructor to return emoloyee model obj
name = map[COL_NAME];
email = map[COL_EMAIL];
}
#override
String toString() {
return 'Contact{name: $name, email: $email}';
}
}
Ok let's evaluate your _initDatabase line by line
first you create the path and check if it exists
var databasepath = await getDatabasesPath();
String path = join(databasepath,_databaseName);
//check existing
var exists = await databaseExists(path);
Seems good, then if it doesn't exist you want to copy it from the AssetFolder
try{
await Directory(dirname(path)).create(recursive: true);
}catch(_){
//copy
ByteData data = await rootBundle.load(join("assets",_databaseName));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
//write
await File(path).writeAsBytes(bytes, flush: true);
}
you try to create the Directory in the path (I don't know what method is dirname but I will believe it returns the path). If nothing fails then it will run
return await openDatabase(path,version: _databaseVersion);
It will enter the catch and copy the db from asset only if the creation of the Directory throws an error, is there a condition when it will fail that? If not then it will never try to copy the db. If you're sure that creating a Directory won't throw an error you should just run the code without the try catch
await Directory(dirname(path)).create(recursive: true);
ByteData data = await rootBundle.load(join("assets",_databaseName));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await File(path).writeAsBytes(bytes, flush: true);
Related
i want to read all data from table "add_news".the code is given below
var db = Mysql();
void _getnews() async{
await db.getConnection().then((conn) async{
// the select query
String sql = "select * from add_news;";
await conn.query(sql).then((results) {
for(var row in results){
print(row);
}
});
conn.close();
});
}
can some please tell me how can i do this??
If you want to show inside your flutter app, then try this.
Display it using future builder. And also make a Model of your database
Repo Link
Future<List<Profiles>> getSQLData() async {
final List<Profiles> profileList = [];
final Mysql db = Mysql();
await db.getConnection().then((conn) async {
String sqlQuery = 'select email, password from users';
await conn.query(sqlQuery).then((results) {
for (var res in results) {
final profileModel =
Profiles(email: res["email"], password: res["password"]);
profileList.add(profileModel);
}
}).onError((error, stackTrace) {
print(error);
return null;
});
conn.close();
});
return profileList;
}
I Have a problem to take the newest data index
class User {
final String idUser,
name,
phone;
User(
{this.idUser,
this.name,
this.phone});
factory User.fromJson(Map<String, dynamic> json) {
return User(
idUser: json['_id'],
name: json['name'],
phone: json['phone']);
}
}
List<User> userFromJson(jsonData) {
List<User> result =
List<User>.from(jsonData.map((item) => User.fromJson(item)));
return result;
}
// index
Future<List<User>> fetchUser() async {
String route = AppConfig.API_ENDPOINT + "userdata";
final response = await http.get(route);
if (response.statusCode == 200) {
var jsonResp = json.decode(response.body);
return userFromJson(jsonResp);
} else {
throw Exception('Failed load $route, status : ${response.statusCode}');
}
}
and the calling method just like this
user = fetchUser();
the "response.body" valued like this
[{"_id":"4136425eb8d9320f4822c554","name":"John","phone":"90643755394"},{"_id":"62766b2eb45s3w0g4662ftd3","name":"Anna","timestamp":"90345765791"}]
I expect it was how to take the first index to get the newest data, but I don't know ho the code will be. Also if there are another soltion to get that newest data, please let me know, thank you very much
Use index to get the specific value from a list
userFromJson(jsonResp[0]); /// For first record
You can use array index number to get the first object in array.
if (response.statusCode == 200) {
var jsonResp = json.decode(response.body);
return List<User>.from(jsonResp.map((user) => User.fromJson(user)));
} else {
throw Exception('Failed load $route, status : ${response.statusCode}');
}
If you want to get one user only
if (response.statusCode == 200) {
var jsonResp = json.decode(response.body);
return User.fromJson(jsonResp[0]);
} else {
throw Exception('Failed load $route, status : ${response.statusCode}');
}
Other method is by modifying the Query using LIMIT 1
Because its Future You have to use the await keyword to get the completed result so modify your code by adding await
users = await fetchUser();
now you can access the user list
var firstUser = users.first;
var firstUser = users[0];
For more await and async you can read this Asynchronous programming
When I try to access my json file from my emulator using a url and a http post request in firebase storage, it transorm into a folder, and when I print data, it gives me the data of the folder not the file.
Code:
final _auth = FirebaseAuth.instance;
final _store = Firestore.instance;
String khatma;
String link;
var data;
down_data() async {
final user = await _auth.currentUser();
await _store.collection('users').document(user.uid).get().then(
(value) => {
setState(
() {
khatma = value.data['Joined'];
},
),
},
);
}
Future getAya() async {
await down_data();
if (khatma == 'Khatma 1') {
var response = await http.post(
'https://firebasestorage.googleapis.com/v0/b/khatma-project.appspot.com/o/Ayat%2Fsurah_1.json?alt=media&token=6bc1994b-6896-4541-a20c-687cbe6e6208',
);
data = jsonDecode(response.body);
print(data);
} else if (khatma == 'Khatma 2') {
setState(() {});
} else if (khatma == 'Khatma 3') {
setState(() {});
} else if (khatma == 'Khatma 4') {
setState(() {});
}
}
#override
void initState() {
getAya();
super.initState();
}
What if I nested the Verse_num to name and taken boolean like this:
"Surah_1": {
"verse_1": {
"name": "بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ",
"taken": "true if taken, flase if not"
},
}
I need to pass json data into my http APIs. I am not able to find the right way to do this yet. Here's my code snippet:
For all interactions to/from API, I have created an Dbhelper class.
Here's my Dbhelper class
class Dbhelper {
String fbody; // json parameter
Map result; // Response json for the api called
Dbhelper({this.fbody});
Future<void> executeData() async {
try {
//Make post request
Response response = await post('http://<my domain>/api/GetInfo',headers: {"content-type":"application/json"},body: $fbody);
var deviceinfo = jsonDecode(response.body);
print('In dbhelper $deviceinfo');
result = deviceinfo;
} catch(e) {
print('Something occured $e');
result = null;
}
}
}
This is what i am trying to do. I have login class which takes input from UI - UserName and password and need to pass this into Dbhelper object.
the intended json to be passed in my API is :
{
"strjson":{ "cUserName":"sandy" , "cPassword":"12345" },
"strSPName":"App_Userlogin"
}
toMap(String u, String p ){
return {
"strSPName":"App_userregister",
"strjson":{
"cUserName":u,
"cPassword":p
}
};
}
void _checkLogin(String u , String p) async {
try {
Map inputs = toMap(u,p);
print(inputs);
Dbhelper db = Dbhelper(fbody: inputs);
await db.executeData();
User user = User.fromJson(db.result);
if (user.uid >0)
Navigator.of(context).pushReplacementNamed('home');
else
print("User not found");
}catch(e){
print(e.toString());
User user = User(uid:0,username:'',userbalance: 0);
}
}
Please help me what I am missing in this
While passing body to http.post request . Try passing body inside single quotes.
Response response = await post('http://<my domain>/api/GetInfo',headers: {"content-type":"application/json"},body: '$fbody');
If this doesn't work, you can try encoding your body in json format using jsonEncode as shown
body: jsonEncode(<String, String> {'uname':'SomeName',})
Hope this works!
Json that I have posted in body..
{
"user": {
"UserName": "username",
"password": "password",
"Name": "name",
"Email": "email"
}
}
Your Post Api call be like:
Future<User> postUser(String username, String password, String name, String
email) async {
Paste your api url here
String url = '';
final response = await http.post(apiUrl, headers: {
// Enter your headers parameter if needed
// E.g:
'Authorization' : 'xyz',
'Content-Type' : 'application/json'
},
body: jsonEncode(<String, String>{
'UserName' : username,
'password' : password,
'Name' : name,
'Email' : email
}));
if (response.statusCode == 200) {
var data = jsonDecode(response.body.toString());
print(data);
return User.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to post user.');
}
}
Your model be like:
class User {
User? user;
User({this.user});
User.fromJson(Map<String, dynamic> json) {
user = json['user'] != null ? new User.fromJson(json['user']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.user != null) {
data['user'] = this.user!.toJson();
}
return data;
}
}
class User {
String? userName;
String? password;
String? name;
String? email;
User({this.userName, this.password, this.name, this.email});
User.fromJson(Map<String, dynamic> json) {
userName = json['UserName'];
password = json['password'];
name = json['Name'];
email = json['Email'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['UserName'] = this.userName;
data['password'] = this.password;
data['Name'] = this.name;
data['Email'] = this.email;
return data;
}
}
Want to ask again ... try implementing the data API stored in a local database ...
the form of the JSON API The object in which there is a JSON Array ... there was an error when wanting to load data from the API to Local database ... roughly this is an error because of "the wrong model or what
Api Service
class MealApiProvider {
Future<List<Categories>> getAllMeal() async {
var url = "https://www.themealdb.com/api/json/v1/1/categories.php";
Response response = await Dio().get(url);
print("Hasil Respon ${response.data}");
return (response.data as List).map((employee) {
print('Inserting $employee');
DBProvider.db.insertMeals(Categories.fromJson(employee));
}).toList();
}
}
Model
class DataMeal {
final List<Categories> categories;
DataMeal({this.categories});
#override
String toString() {
return 'DataMeal{categories: $categories}';
}
factory DataMeal.fromJson(Map<String, dynamic> json) {
return DataMeal(
categories: List<Categories>.from(
json["categories"].map(
(categories) {
return Categories.fromJson(categories);
},
),
),
);
}
Map<String, dynamic> toJson() => {
"categories": List<dynamic>.from(
categories.map(
(x) => x.toJson(),
),
),
};
}
Local DB
initDB() async {
Directory documentsDirectory = await getApplicationDocumentsDirectory();
final String path = join(documentsDirectory.path, '$nameDatabase');
print('insert database $path');
return await openDatabase(path, version: 1, onOpen: (db) {},
onCreate: (Database db, int version) async {
await db.execute('CREATE TABLE $nameTable('
'idCategory,'
'strCategory TEXT,'
'strCategoryThumb TEXT,'
'strCategoryDescription TEXT'
')');
});
}
insertMeals(DataMeal newMeal) async {
await deleteAllMeal();
final Database db = await database;
final res = await db.insert("$nameTable", newMeal.toJson());
print("inserting data $res");
return res;
}
Error
return (response.data as List).map((employee)
Respon Data
Your response contains map at the begining !
Try this
class MealApiProvider {
Future<List<Categories>> getAllMeal() async {
var url = "https://www.themealdb.com/api/json/v1/1/categories.php";
Response response = await Dio().get(url);
print("Hasil Respon ${response.data}");
//***Change below line****
return (response.data['categories'] as List).map((employee) {
print('Inserting $employee');
DBProvider.db.insertMeals(Categories.fromJson(employee));
}).toList();
}
}
instead of
class MealApiProvider {
Future<List<Categories>> getAllMeal() async {
var url = "https://www.themealdb.com/api/json/v1/1/categories.php";
Response response = await Dio().get(url);
print("Hasil Respon ${response.data}");
//*** I change the below line !
return (response.data as List).map((employee) {
print('Inserting $employee');
DBProvider.db.insertMeals(Categories.fromJson(employee));
}).toList();
}
}