How to make and relate complex table with each other in sqfllite flutter? - flutter

I am using sqflite package to store data offline as well once it got from API. I had seen a couple of examples and all used the simple Strings and not lists in their models as a type and due to that I am feeling difficulty in the conversion of these classes in respective tables and link them so that data can be fetch easily once synced. Can someone guide me on how to make create and link tables in sqflite with these types of classes so that they work perfectly?
TodayDeliveriesModel class
class TodayDeliveriesModel {
final String Name;
final List<ItemsModel> allItems;
final bool pending;
TodayDeliveriesModel({this.Name, this.allItems, this.pending});
}
Items Model class:
class ItemsModel {
String name;
String quantity;
ItemsModel({this.name, this.quantity});
}

fetch and Parse JSON data from the server.
Create Database Table with just 3 parameters.
class DeliveryModel{
String name;
String items;
bool isPending;
}
then when you save data in the database, just covert List to String
and save this string as the items.
After then when you get this string from database convert this into again List

Related

HiveError: This object is not currently in a box. When trying to save a hive object in a list in another hive object

I'm working on an app with flutter and hive local nosql database.
I made a hive object that contains a list of another hive object.
This is the first object:
#HiveType(typeId: 0)
class FirstObject extends HiveObject {
#HiveField(0)
late String string;
#HiveField(1)
late DateTime dateTime;
#HiveField(2)
late List<SecondObject> secondObject = [];
}
This is the second object:
#HiveType(typeId: 1)
class SecondObject extends HiveObject {
#HiveField(0)
late String something;
#HiveField(1)
bool boolean = false;
#HiveField(2)
late DateTime? date;
}
I generated adapters for both objects and registered them but I generated only one box for the first object that contains the second object.
Then a list variable representing the list in the first object and made a listview builder that has list tiles with a checkbox that updates the boolean in the second object and then saves it.
But when I test it it gives me an error saying:
The following HiveError was thrown while handling a gesture:
This object is currently not in a box.
I tried some solutions like making another box for the second object and declaring a variable in the second object containing the first object that is belongs to. But those solutions gave me other errors.
What is the best solution to this problem?
Now I realized that I can save the first container object instead of just the second object.

Flutter / Inject.dart - Is it possible to simplify or generate code for a 'provided' class instantiation?

Been doing some research on Flutter Dependency Injection,and I kinda settled on Inject.dart
However, I am having some trouble using inject.
Is there any way to simplify instantitation of a injected class?
I have this MyClass, which I need to instantiate passing a HomeStore, however, how can I instatiate it without calling global acessors? (such as the ones made on the Injector file).
It seems I could just use the Get_It package otherwise, which would get me the same results, and without code generation, but I don't quite like the whole global access thing.
My sample:
// current code
class MyClass(){
store = HomeStore(AppInjector().globalHudStore, AppInjector().globalErrorStore);
}
// desired code
class MyClass(){
#instance ?
store = HomeStore();
store = HomeStore.instanciate?();
}
class HomeStore {
#provide
HomeStore(this._globalHudStore, this._globalErrorStore);
final GlobalHudStore _globalHudStore;
final ErrorStore _globalErrorStore;
}
If you are willing to work with json, you might want to consider this package json_serializable. Just search for it at pub.dev.
I can give a little example. Let's say you have a User class/model.
part 'user.g.dart';
#JsonSerializable()
class User {
int id;
#JsonKey(name: 'user_type_id')
int userTypeId;
String email;
#JsonKey(name: 'user_detail')
UserDetail userDetail;
#JsonKey(name: 'user_type')
UserType userType;
#JsonKey(name: 'user_location')
UserLocation userLocation;
User();
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
and you fetched a User data via API, and want to create a User variable and fill it with data without having to do that manually.
You can actually do that with just this line of code
User user = User.fromJson(jsonUser);
These even automatically json serializes classes in your User class, as long as those classes are also json serializable, which is defined with #JsonSerializable()
So even with just that single line of code, if the jsonUser which came from the API also has values for UserDetail, UserType, and UserLocation, you can also access them.

sqlite database /retrofit (json object)

im a newbie here. my problem goes with this; i like to send all my data created from my sqlite database and send it all to my custom api via json object. is this possible? if is it, can you give me reference on how to do it? because i can't find any solution for this. thanks you :)
This is my database from my mobile ive like to fetch on retrofit
The easiest way is to create an Object for your data then convert that Object to json via GSON.
public class Data {
private int id;
private double latitude;
private double longitude;
private long dateTime;
private int syncStatus;
//Create a constructor for all fields
//Don't forget to generate setters/getters
}
Then set the data for the Object
Data data = new Data(id, latitude, longitude, datetime, synctime);
To convert the Object to Json
Gson gson = new Gson();
String json = gson.toJson(data);
You can also use the Object directly without using GSON via Retrofit.
public interface GetDataService {
#POST("/api/data")
Call<Data> createData(#Body Data data);
}
Also use ORM when using sqlite.

flutter assign list values to a class

Looking for help for assigning List values to a class. Here is my class.
class Specialties {
int id;
String name;
String details;
const Specialties(this.id, this.name, this.details);
}
I have a List created from JSON and I have confirmed it has values, but can not get the values assigned to instantiate the class. I know the class works as when I hardcode values it gets created just fine.
This is how I am trying to do it and can not find why it does not work.
Specialties getSpec(int index) {
return new Specialties(mylist[index].id, mylist[index].name, mylist[index].details);
}
I am sure I am missing something easy, but once I saw hardcoded values working, can not figure it out.
Any help would be great.
It seems like you may be coming from a JavaScript background where object.property
object['property'] are equivalent. In Dart, they are not.
If you parsed a JSON object it will turn into a Dart Map with String keys. Modify your getSpec function to use operator[] instead of dot syntax to read the entries of the Map.
Specialties getSpec(int index) {
return new Specialties(mylist[index]['id'], mylist[index]['name'], mylist[index]['details']);
}
You may want to consider giving Specialties an additional fromMap constructor rather than constructing it in an external function. You should also make the fields of Specialties be final since its constructor is const.
class Specialties {
final int id;
final String name;
final String details;
const Specialties(this.id, this.name, this.details);
factory Specialties.fromMap(Map data) => new Specialties(data['id'], data['name'], data['details']);
}
Then you can say
new Specialties.fromMap(mylist[index])
Finally, there are some other JSON deserialization libraries that you might want to consider to reduce the amount of boilerplate deserialization code: Jaguar, built_value.
If you have a JSON string in the form of '[{"id": 1, "name": "ab", "details": "blabla"},{...}]' you can convert it like this:
List<Specialties> specialties(String jsonstring) {
List parsedList = JSON.decode(jsonstring);
return parsedList.map((i) => new Specialties(
i["id"], i["name"], i["details"]));
}
You will have to import dart:convert to get the method JSON.decode

Storing relationships in Realm (Java)

I'm starting to use Realm to store objects in my Android app. Here's an example of what I'm looking to store:
public class Item implements RealmModel {
String id;
...
}
I have multiple lists that display items. The number of lists can keep expanding (the user can create as many lists as possible.
Let's say the user create's a list called "Best". When I'm viewing the "Best" list I call getItems("Best") which gets a List<Items> from the API. I now have to figure out how to store this list. In SQLite world I would have create a new table "custom_list_best", for example, which is just a single list of all the Item.id's that are part of the list. I would also have an "items" table that has all the distinct Items. To get items in the best list I would simply do a join query on both the best and items tables.
In the Realm world I'm trying to figure out how Realm works and what's the best way to build my models.
I initially thought I could create an object called CustomList:
public class CustomList implements RealmModel {
String listId;
RealmList<Item> items;
}
I would then store a RealmList<CustomList>. But the only issue is I also want to be able to query against all Items. So I need to also store a RealmList<Item> in Realm. How does Realm work in this case? If I store a separate RealmList<Item> and then store each RealmList<CustomList> will it not duplicate data?
Instead will I have to manually handle this by doing this instead:
public class CustomList implements RealmModel {
String listId;
List<String> itemIds;
}
And then query for Item.class objects that have itemId in itemIds from above object?
In SQLite world I would have create a new table "custom_list_best",
No, you would have a table called custom_lists with an auto-increment ID and an identifier, and a join table called join_custom_lists_items that would contain the ID of custom_lists and the ID of any item that belongs to that given custom list.
In the Realm world I'm trying to figure out how Realm works and what's the best way to build my models.
If the ID of the item is concrete and you need to be able to store the same Item in multiple lists, then in order to access the lists in both directions, you'll need a RealmList<? extends RealmModel> in both cases.
#RealmClass
public class Item implements RealmModel {
#PrimaryKey
private String id;
private RealmList<CustomList> customLists;
// getter setter
}
And
#RealmClass
public class CustomList implements RealmModel {
#PrimaryKey
private String title; // assuming you cannot name two lists the same? otherwise do `#Index`
private RealmList<Item> items;
// getter setter
}
This way you can do
realm.executeTransaction(new Realm.Transaction() {
public void execute(Realm realm) {
Item item = realm.where(Item.class).equalTo(ItemFields.ID, itemId).findFirst(); // assuming exists
CustomList customList = realm.where(CustomList.class).equalTo(CustomListFields.TITLE, "Best").findFirst();
if(customList == null) {
customList = realm.createObject(CustomList.class, "Best");
}
customList.getItems().add(item);
item.getCustomLists().add(customList);
}
}
And then you can query
RealmResults<Item> bestItems = realm.where(Item.class)
.equalTo(ItemFields.CustomLists.TITLE, "Best")
//same as "customLists.title"
.findAll();
All this Fields stuff I'm using is from https://github.com/cmelchior/realmfieldnameshelper