How to create complex model on Sqflite on Flutter - flutter

I have a complex model and could not able to save them on locally wiht Sqflite (Flutter).
I am able to save the base model on db. But I could not save others.
I try to do it like this.(Video has multiple data)
int res = await dbClient.insert("$tableName", game.toMap());
for (var i = 0; i < object.videos.length; i++) {
Video expectedList = Video.map(object.videos[i]);
int res2 = await dbClient.insert("video", expectedList.toMap());
}
This is the base model;
int versionParent;
double popularity;
String key;
String versionTitle;
dynamic keywords = List<Keyword>();
dynamic videos = List<Video>();
dynamic genres = List<Genres>();
This is the map function on model;
var map = Map<String, dynamic>();
map['genres'] = genres;
map['id'] = id;
map['keywords'] = keywords;
map['key'] = key;
map['versionTitle'] = versionTitle;
map['popularity'] = popularity;
map['videos'] = videos;
return map;
}
this is one of the dynamic list file model;
int _id;
int _game;
String _name;
String _videoId;
Map<String, dynamic> toMap() {
var map = Map<dynamic, dynamic>();
map['id'] = id;
map['game'] = game;
map['name'] = name;
map['video_id'] = videoId;
return map;
}
this is the tables I created (I create table for all of the dynamic lists)
await db.execute('CREATE TABLE $tableName(id INTEGER PRIMARY KEY,hypes INTEGER, updatedAt INTEGER, pulseCount INTEGER, coverCoverId INTEGER, versionParent INTEGER, popularity INTEGER, firstReleaseDate INTEGER, key TEXT , url TEXT, name TEXT, slug TEXT, summary TEXT, imageCoverId TEXT, versionTitle TEXT)');
await db.execute(
'CREATE TABLE video(id INTEGER PRIMARY KEY, game INTEGER, name TEXT, videoId TEXT)');

Related

Flutter Sqflite how to get data from table and pass it to provider

In my app these is a localdb containing user data which i have parsed from API. My objective is to get these values from local table and use that values for state management using provider. I have created a model class for the table
class UserTable {
int? id;
String? accountDetails;
String? accountId;
String? childName;
String? childGender;
int? expiry;
int? finalSequenceNo;
int? packageIndex;
String? parentName;
String? productType;
String? userId;
int? age;
int? dob;
int? nextSyncTime;
String? productSubType;
String? validTill;
int? latestUpdatePkgSeqNo;
int? guidedTour;
UserTable(
{this.id,
this.accountDetails,
this.accountId,
this.childName,
this.childGender,
this.expiry,
this.finalSequenceNo,
this.packageIndex,
this.parentName,
this.productType,
this.userId,
this.age,
this.dob,
this.nextSyncTime,
this.productSubType,
this.validTill,
this.latestUpdatePkgSeqNo,
this.guidedTour,
});
Map<String, dynamic> toMap() {
var map = <String, dynamic>{
DatabaseHelper.USER_TABLE_ID: id,
DatabaseHelper.ACCOUNT_DETAILS: accountDetails,
DatabaseHelper.ACCOUNT_ID: accountId,
DatabaseHelper.USER_CHILD_NAME: childName,
DatabaseHelper.USER_CHILD_GENDER: childGender,
DatabaseHelper.EXPIRY: expiry,
DatabaseHelper.FINAL_SEQ_NO: finalSequenceNo,
DatabaseHelper.PACKAGE_INDEX: packageIndex,
DatabaseHelper.PARENT_NAME: parentName,
DatabaseHelper.PRODUCT_TYPE: productType,
DatabaseHelper.USER_ID: userId,
DatabaseHelper.AGE: age,
DatabaseHelper.DOB: dob,
DatabaseHelper.NEXT_SYNC_TIME: nextSyncTime,
DatabaseHelper.PRODUCT_SUB_TYPE: productSubType,
DatabaseHelper.VALID_TILL: validTill,
DatabaseHelper.LATEST_UPDATED_PKG_SEQ_NO: latestUpdatePkgSeqNo,
DatabaseHelper.GUIDED_TOUR: guidedTour,
};
if (id != null) {
map[DatabaseHelper.USER_TABLE_ID] = id;
}
return map;
}
UserTable.fromMap(Map<String, dynamic> map) {
id = map[DatabaseHelper.USER_TABLE_ID];
accountDetails = map[DatabaseHelper.ACCOUNT_DETAILS];
accountId = map[DatabaseHelper.ACCOUNT_ID];
childName = map[DatabaseHelper.USER_CHILD_NAME];
childGender = map[DatabaseHelper.USER_CHILD_GENDER];
expiry = map[DatabaseHelper.EXPIRY];
finalSequenceNo = map[DatabaseHelper.FINAL_SEQ_NO];
packageIndex = map[DatabaseHelper.PACKAGE_INDEX];
parentName = map[DatabaseHelper.PARENT_NAME];
productType = map[DatabaseHelper.PRODUCT_TYPE];
userId = map[DatabaseHelper.USER_ID];
age = map[DatabaseHelper.AGE];
dob = map[DatabaseHelper.DOB];
nextSyncTime = map[DatabaseHelper.NEXT_SYNC_TIME];
productSubType = map[DatabaseHelper.PRODUCT_SUB_TYPE];
validTill = map[DatabaseHelper.VALID_TILL];
latestUpdatePkgSeqNo = map[DatabaseHelper.LATEST_UPDATED_PKG_SEQ_NO];
guidedTour = map[DatabaseHelper.GUIDED_TOUR];
}
}
How can I retrieve data from localdb , so that I can use that data for statemanagement. Below is how now i'm retrieving data.
Future<List<UserTable>> getAllUserData() async {
final db = await this.database;
final List<Map<String, dynamic>> map =
await db!.rawQuery("SELECT * FROM $TABLE_USER");
List<UserTable> list = map.isNotEmpty?map.map((e) => UserTable.fromMap(e)).toList():[];
return list;
How can i achieve this? please suggest any workarounds

How to create a model in flutter

I'm watching the old flutter course because I couldn't really find a new one. But since flutter is constantly updated, it becomes a little more challenging as soon as you learn from the old courses.
Here is my questions:
Is fromObject still here or just changed to fromJson?
Do you have a model sample?
How can I do my _id is unique?(Usin sql etc.)
I'm trying something like this but I'm getting an error in 'Product.fromObject'.
class Product {
int _id;
String _name;
String _description;
double _price;
Product(this._id, this._name, this._description, this._price);
Product.withId(this._id, this._name, this._description, this._price);
int get id => _id;
String get name => _name;
String get description => _description;
double get price => _price;
set name(String value) {
if (value.length >= 2) {
_name = value;
}
}
set description(String value) {
if (value.length >= 10) {
_description = value;
}
}
set price(double value) {
if (value > 0) {
_price = value;
}
}
Map<String, dynamic> toMap() {
var map = <String, dynamic>{};
map["name"] = _name;
map["description"] = _description;
map["price"] = _price;
map["id"] = _id;
return map;
}
Product.fromObject(dynamic o) {
_id = o["id"];
_name = o["name"];
_description = o["description"];
_price = o["price"];
}
}```
Now It's changed to fromJson.
class Post{
int userid;
int id;
String title;
String body;
Post({userid, id, title, body});
Post fromJson(Map<String, dynamic> json){
Post post = Post();
post.userid = json["userId"];
post.id = json['id'];
post.title = json['title'];
post.body = json['body'];
return post;
}
Map<String, dynamic> toJson(Post post){
Map<String, dynamic> data = {
"userId": post.userid,
"id": post.id,
"title": post.title,
"body": post.body
};
return data;
}
}
I have attached a sample model class for your reference.
You can read about json serialization here: https://flutter.dev/docs/development/data-and-backend/json
The correct method to parse from json is a factory method that is called fromJson and takes a map.

How to get SQFlite data date wise in flutter?

I'm creating todo app in flutter. And I need to show Todos date wise. Like all Todos created today should shown under Today, all the tomorrow's Todos should shown under Tomorrow.
I have created my table like this:
database.execute("""
CREATE TABLE Todotable(
id INTEGER PRIMARY KEY AUTOINCREMENT,
taskName TEXT NOT NULL,
taskTag TEXT NOT NULL,
date TEXT NOT NULL,
isReminder INTEGER NOT NULL,
isCompleted INTEGER NOT NULL
)
""");
I don't know how to query SQFlite data date wise and format it like Today and Tomorrow. And show in section like today and tomorrow as shown in design.
Thanks for answers:)
for getting todos for tomorrow
//for tomorrow
String tomorrowDate= DateTime.now().add(Duration(days: 1)).toIso8601String();
var todosForTomrrow= await database
.rawQuery('SELECT * FROM Todotable WHERE date = ?', [tomorrowDate]);
//for today
String todayDate= DateTime.now().toIso8601String();
var todosForToday= await database
.rawQuery('SELECT * FROM Todotable WHERE date = ?', [todayDate]);
Date is converted and saved here in string format and date should converted to same format before inserting into the table like this
You can create DATETIME columns in sqflite.
Here is an example for a Weather table created in a sqflite database:
batch.execute('''
CREATE TABLE $tableWeather (
$weatherLocalization TEXT NOT NULL,
$weatherDate DATETIME NOT NULL,
$weatherHumidityPercentage REAL,
$weatherWindDegree REAL,
$weatherWindSpeed REAL,
$weatherPressureHPascal INTEGER,
$weatherTemperatureCelsius REAL,
$weatherDescription TEXT,
$weatherIconId TEXT,
PRIMARY KEY($weatherLocalization, $weatherDate));
''',);
You can create a Weather object as follows:
class Weather{
String localization;
DateTime date;
double humidityPercentage;
double windDegree;
double windSpeedMS;
int pressureHPascal;
double temperatureCelsius;
String description;
String iconId;
Weather({
#required this.localization,
#required this.date,
this.humidityPercentage,
this.windDegree,
this.windSpeedMS,
this.pressureHPascal,
this.temperatureCelsius,
this.description,
this.iconId
});
//to be used when inserting a row in the table
Map<String, dynamic> toMap() {
final map = new Map<String, dynamic>();
map["$weatherLocalization"] = localization;
map["$weatherDate"] = date.toString();
map["$weatherHumidityPercentage"] = humidityPercentage;
map["$weatherWindDegree"] = windDegree;
map["$weatherWindSpeed"] = windSpeedMS;
map["$weatherPressureHPascal"] = pressureHPascal;
map["$weatherTemperatureCelsius"] = temperatureCelsius;
map["$weatherDescription"] = description;
map["$weatherIconId"] = iconId;
return map;
}
//to be used when converting the row into object
factory WeatherOnDate.fromMap(Map<String, dynamic> data) => new WeatherOnDate(
localization: data["$weatherLocalization"],
date: DateTime.parse(data["$weatherDate"]),
humidityPercentage: data["$weatherHumidityPercentage"],
windDegree: data["$weatherWindDegree"],
windSpeedMS: data["$weatherWindSpeed"],
pressureHPascal: data["$weatherPressureHPascal"],
temperatureCelsius: data["$weatherTemperatureCelsius"],
description: data["$weatherDescription"],
iconId: data["$weatherIconId"]
);
}
Be careful to transform your DateTime attribute to a String or int as I did in the toMap() function.
Then, when you want to fetch a date you can do this:
Future<Weather> fetchWeatherOnDate(DateTime dateTime) async {
DatabaseHelper _databaseHelper = Injection.injector.get();
List<Map<String, dynamic>> weatherMaps = await _databaseHelper.db.rawQuery(
'SELECT * FROM $tableWeather WHERE DATE($weatherDate) = DATE(?)',
[dateTime.toString()]);
List<Weather> weathers= [];
for (final weatherMap in weatherMaps) {
weathers.add(Weather.fromMap(weatherMap));
}
if (weathers.isNotEmpty){
return weathers[0];
}
return null;
}
DateTime today = DateTime.now()
Weather weatherToday = fetchWeatherOnDate(today);
I think that it gives you a good idea of how to solve your problem :)
DateTime is not supported in Flutter SQLite package.
Check the information about supported SQLite types:
https://pub.dev/packages/sqflite#supported-sqlite-types
DateTime is not a supported SQLite type. Personally I store them as int (millisSinceEpoch) or string (iso8601)
We can use String or int as suggested from the package developer.
To work with a conditional selection of items of day in DB, perhaps a String is more convenient.
Personally, I prefer user formatter to get the search keyword, as shown below:
DateFormat formater = DateFormat('yyyyMMdd');
var today = formater.format(DateTime.now());
var tomorrow = formater.format(DateTime.now().add(const Duration(days: 1)));
To search in DB, I'd use a method like below:
Future<TodoList?> getTodoListByDay(String day) async {
final db = await database;
String sql =
"SELECT * FROM Todotable WHERE date = \'${day}\' ";
var res = await db.rawQuery(sql);
List<TodoList> objs = res.isNotEmpty
? res.map((c) => TodoList.fromMap(c)).toList()
: [];
return objs.isNotEmpty ? objs : null;
}
TodoList class could be generate from json, as I do with 'jsonToDartModel' package.
import 'dart:convert';
class TodoList {
int? id;
String? taskName;
String? taskTag;
String? date;
int? isReminder;
int? isCompleted;
TodoList({
this.id,
this.taskName,
this.taskTag,
this.date,
this.isReminder,
this.isCompleted,
});
factory TodoList.fromMap(Map<String, dynamic> data) => TodoList(
id: data['id'] as int?,
taskName: data['taskName'] as String?,
taskTag: data['taskTag'] as String?,
date: data['date'] as String?,
isReminder: data['isReminder'] as int?,
isCompleted: data['isCompleted'] as int?,
);
Map<String, dynamic> toMap() => {
'id': id,
'taskName': taskName,
'taskTag': taskTag,
'date': date,
'isReminder': isReminder,
'isCompleted': isCompleted,
};
/// `dart:convert`
///
/// Parses the string and returns the resulting Json object as [TodoList].
factory TodoList.fromJson(String data) {
return TodoList.fromMap(json.decode(data) as Map<String, dynamic>);
}
/// `dart:convert`
///
/// Converts [TodoList] to a JSON string.
String toJson() => json.encode(toMap());
}

flutter UniqueKey cast to another type of data sqflite

I have a field in a class of type UniqueKey called "_id":
class RegistroAnsiedad{
late final UniqueKey _id;
late final int _estado_animo;
late final int _fecha;
late final int _nivel_ansiedad;
late final int _actividad;
RegistroAnsiedad(
this._estado_animo,
this._fecha,
this._nivel_ansiedad,
this._actividad,
[UniqueKey? id]
):this._id = id ?? UniqueKey();
Map<String, Object?> toMap() {
var mapa = <String, dynamic>{
"_fecha": _fecha,
"_nivel_ansiedad": _nivel_ansiedad,
"_actividad": _actividad
};
if (id != null) {
mapa["_id"] = _id;
}
return mapa;
}
....
When I want to write a record of the above type in sqflite with the following code:
registro_ansiedad = RegistroAnsiedad(
controlador_actividad.estado_animo.value,
controlador_actividad.fecha.value,
controlador_actividad.nivel_ansiedad.value,
numero_actividad);
//Se inserta el registro
final int id_fila = await dbHelper.inserta(registro_ansiedad.toMap());
I get the following error:
Invalid argument [#adc81] with type UniqueKey.
I/flutter ( 6002): Only num, String and Uint8List are supported.
I know my mistake is trying to write a UniqueKey to Sqflite when it only supports integer, text, ...
How can I convert my UniqueKey field to integer or text?
Thank you in advance
Daniel Leyva
I could use a autoincrement field and so I should not have to convert to UniqueKey

How can we parse the result fetched from odoo using the odoo_api in flutter?

I used the odoo_api v1.0.2 package in order to fetch all the records from odoo.
final domain = [
["sale_ok", "!=", false]
];
var fields = ["name", "list_price"];
client
.searchRead("product.template", domain, fields)
.then((OdooResponse result) {
if (!result.hasError()) {
print("Succesful");
final data = result.getResult();
print("Total: ${data['length']}");
final records = ("${data["records"]}");
print(records);
} else {
print(result.getError());
}
});
I want to take individual record from the product list in odoo and display it as products in my flutter app.
Create a model like:
class ItemModel {
final int id;
final String type;
final int time;
final String text;
final bool dead;
ItemModel.fromJson(Map<String, dynamic> parsedJson)
: id = parsedJson['id'],
type = parsedJson['type'],
time = parsedJson['time'],
text = parsedJson['text'],
dead = parsedJson['dead'];
Map<String, dynamic> toMap() {
return <String, dynamic>{
"id": id,
"type": type,
"time": time,
"text": text,
"dead": dead,
};
}
}
And use like ->
final item = ItemModel.fromJson(parsedJson);