i want save list of object in local memory by shared_preferences my Model :
class Vehicle {
final String vehicleId;
final String vehicleType;
Vehicle({
this.vehicleId,
this.vehicleType,
});
}
after when i search about this i found half-solution :) to convert to List<String> and add this to my class :
factory Vehicle.fromJson(Map<String, dynamic> vehicleJson){
return new Vehicle(
vehicleId: vehicleJson['vehicleId'],
vehicleType: vehicleJson['vehicleType'],
);
}
Map<String, dynamic> toJson(){
return {
'vehicleId': this.vehicleId,
'vehicleType' : this.vehicleType,
};
}
but i can't found how can i save and get it :(
sorry my English not good
Actually you cannot save a list of object with shared preferences but you can encode each object into a string and save it using setStringList() function
Example:
List<String> vehiculesEncoded = [];
vehicles.forEach((vehicule) {
vehiculesEncoded.add(vehicule.toJson());
});
sharedPreferences.setStringList("myAmazingListOfVehicules", vehiculesEncoded);
this type of array you have & you want to store it in session
List<Vehicle> arrayVehicle = [ your data ];
for that you have to convert array into json string by doing this
String strTemp = json.encode(arrayVehicle);// store this string into session
whenever you want to retrive it just decode that string
List<Vehicle> arrayVehicle = json.decode(yourSessionValue)
Related
I'm struggling a bit with getting data I push to Firebase Realtime DB in Flutter.
I'm using this code to push data to FB:
DatabaseReference newPostRef = news_dbRef.push();
final newKey = news_dbRef.child('News').push().key;
newPostRef.set({
"timestamp": timestamp,
"content": content_u,
"title": title_u,
"imgURL": imageUrl_u.substring(0,imageUrl_u.lastIndexOf('?')),
"fileURL": fileUrl_u.substring(0,fileUrl_u.lastIndexOf('?')),
"user": _user
});
so it creates a desired object in Firebase like this:
screenshot from Firebase
Now when I'm trying to get this data to my app, I'm having issues with proper serialization with it.
This is what I'm doing:
DatabaseReference newsCountRef =
FirebaseDatabase.instance.ref().child('News');
newsCountRef.onValue.listen((DatabaseEvent event) {
var data = event.snapshot.value;
String encoded = jsonEncode(data);
Map<String, dynamic> postslist = jsonDecode(encoded);
var somelist = postslist.entries.map((e) => TestNewsModel(e.key, e.value)).toList();
so it brings me to a stage that I have a list... but cannot read values for each line.
Do you have any ideas what I'm missing? Here's a class I'm using for serialization:
class TestNewsModel {
String recordid;
dynamic fields;
TestNewsModel(this.recordid, this.fields);
String toString() {
return '{ ${this.recordid}, ${this.fields} }';
}
}
class Field {
String timestamp;
String content;
String title;
String imgURL;
String fileURL;
String user;
Field({
required this.timestamp,
required this.content,
required this.title,
required this.imgURL,
required this.fileURL,
required this.user,
});
String toString() {
return '{ ${this.timestamp}, ${this.content}, ${this.title}, ${this.imgURL}, ${this.fileURL}, ${this.user} }';
}}
Would recommend creating a .fromDoc method in your class, similar to how you would create a .fromJson method.
Heres an example from one of my projects, this way you can avoid encoding and decoding.
///Creates a [Patient] from the information from a single firestore doc.
factory Patient.fromDoc(doc) {
return Patient(
doc.data()['email'],
doc.data()['forename'],
doc.data()['surname'],
doc.data()['hospitalNum'].toString(),
doc.id,
);
}
How do we store model data to flutter secure storage... or does it supports it?
I have a model like this... I load data from my API to this model... once I have data, I wanted to save it to the flutter secure storage and vice versa(load entire data to model from flutter secure storage)...
class MyUserModel {
MyUserModel({
this.authKey,
this.city,
this.contact,
this.email,
this.isContact,
this.userId,
});
String authKey;
String city;
String contact;
dynamic email;
bool isContact;
int userId;
}
Of course, I know we can read and write data like below... I am just checking if there is a way where we can directly write it from the model...
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
// Create storage
final storage = new FlutterSecureStorage();
// Read value
String value = await storage.read(key: key);
// Write value
await storage.write(key: key, value: value);
I saw hive supports this feature out of the box but I realized that it takes little time (2-3 sec) for initialization also Author is working on an alternative to hive due to two major blocks... the new database called Isar which clears all roadblock but it is still in development...
if it is possible then please share the sample code...
to save the object:
convert your object to map with toMap() method
serialize your map to string with serialize(...) method
save the string into secure storage
for restoring your object:
deserialize secure storage string to a map with deserialize(...) method
use fromJson() method to get your object
by that, you will serialize your data into a string and save and retrieve them.
class MyUserModel {
String authKey;
String city;
String contact;
dynamic email;
bool isContact;
int userId;
MyUserModel({
required this.authKey,
required this.city,
required this.contact,
required this.email,
required this.isContact,
required this.userId,
});
factory MyUserModel.fromJson(Map<String, dynamic> jsonData) =>
MyUserModel(
authKey: jsonData['auth_key'],
city: jsonData['city'],
contact: jsonData['contact'],
email: jsonData['email'],
isContact: jsonData['is_contact'] == '1',
userId: jsonData['user_id'],
);
}
static Map<String, dynamic> toMap(MyUserModel model) =>
<String, dynamic> {
'auth_key': model.authKey,
'city': model.city,
'contact': model.contact,
'email': model.email,
'is_contact': model.isContact ? '1' : '0',
'user_id': model.userId,
};
static String serialize(MyUserModel model) =>
json.encode(MyUserModel.toMap(model));
static MyUserModel deserialize(String json) =>
MyUserModel.fromJson(jsonDecode(json));
}
Usage:
final FlutterSecureStorage storage = FlutterSecureStorage();
await storage.write(key: key, value: MyUserModel.serialize(model));
MyUserModel model = MyUserModel.deserialize(await storage.read(key: key));
You can do this by encoding your Model into json saving it in Secure Storage and then decode the json and get the model back.
// Saving model into Storage
static Future<void> setMyUserModel(MyUserModel user) async {
await const FlutterSecureStorage().write(
key: 'user', value: user.toRawJson());
}
// Getting model from storage
static Future<MyUserModel> getMyUserModel() async {
return MyUserModel.fromRawJson(
await const FlutterSecureStorage().read(key: 'user') ??
'{}');
}
And of course you need to implement fromRawJson() and toRawJson() inside your model.
Sorry for the late reply :P.
To do this, encode your model into JSON and store it in secure storage. Later, decode the JSON to retrieve the model.
final storage = FlutterSecureStorage();
static const String modelData = "modelData";
// Saving model into Storage
static Future<void> setModel(user) async {
final jsonDataEncoded = jsonEncode(jsonData);
await storage.write(key: modelData , value: jsonDataEncoded);
}
//call this when you want to store your data to secured storage
ClassName.setModel(decodedResponse);//decode your json and send it here
//to read data from the local storage || secured storage
static Future<MyModel> getDataFromLocalStorage() async {
final jsonModel = await storage.read(key: modelData);
final jsonData = jsonDecode(jsonModel.toString());
final items = List.from(jsonData);
dataList = items.map((e) => MyModel.fromJson(e)).toList();
return dataList;
}
List<Data> datas = [];
Future<List<Data>> getData() async {
final response =
await http.get('https://iptv-org.github.io/iptv/index.country.m3u');
final m3u = await M3uParser.parse(response.body);
for (final entry in m3u) {
Data data = Data(entry.title, entry.attributes['tvg-logo'], entry.link,
entry.attributes['tvg-language'], 'false');
datas.add(data);
}
return datas;
}
class Data {
String title;
String logo;
String url;
String language;
String isFavorite = 'false';
Data(this.title, this.logo, this.url, this.language, this.isFavorite);
}
Everytime I get the data from the url, then how I gonna save the list of Data object? Can I save the data using sharedPref?
for complicated data its recommended to use the database. you can use SqfLite package as a database. but u can also use shared Preferences too. for creating Model use quicktype.io it will create your model with several useful methods such as toJson and fromJson. it will also generate fromRawJson and toRawJson. these two methods work with String. you can convert your model to string and stored to SharedPreferences and when you need it again take it and convert it to model.
I am setting up my model classes to confirm to the docs for sqflite which suggest including a named constructor to convert to/from Maps to better handling of data between the classes and the DB. Every example I can find is very simple, with class properties all being simple data types.
Using the constructor and method shown below, converting to/from Map is quite simple when dealing with a class such as this.
class Human{
final String name;
final String height;
Final String weight;
Human({this.name, this.height, this.weight});
}
However, when you have a class where one of the fields is a bit more complex, I do not understand how to structure things within the named constructor and xxx method to return the map of data that I 'believe' I should get.
class Human{
final String name;
final String height;
Final String weight;
List<Child> children = [];
Human({this.name, this.height, this.weight, this.children});
}
Human({this.name, this.height, this.weight, this.children});
Human.fromMap(Map<String, dynamic> map)
: name = map['name'],
height = map['height'],
weight = map['weight'],
children = map['children'];
Map<String, dynamic> toMap() {
return {
'name': name,
'height': height,
'weight': weight,
'children': children,
};
}
The List children is the part I am struggling with. I believe you have to get each Child object ALSO converted to a map within the parent map, but am losing the battle here.
Is my approach way off here? Is there some other method I should be using to accomplish this?
Any assistance would be much appreciated.
Here I am explaining the following
How to convert a model object into Map to use with sqlite
How to convert a Map object from sqlite into a model class.
How to parse JSON reponse properly in flutter
How to convert a model object into JSON
All of the above questions has same answer. Dart has great support for these operations. Here I am going to illustrate it with a detailed example.
class DoctorList{
final List<Doctor> doctorList;
DoctorList({this.doctorList});
factory DoctorList.fromMap(Map<String, dynamic> json) {
return DoctorList(
doctorList: json['doctorList'] != null
? (json['doctorList'] as List).map((i) => Doctor.fromJson(i)).toList()
: null,
);
}
Map<String, dynamic> toMap() {
final Map<String, dynamic> data = Map<String, dynamic>();
if (this.doctorList != null) {
data['doctorList'] = this.doctorList.map((v) => v.toMap()).toList();
}
return data;
}
}
The above DoctorList class has a member which holds a list of 'Doctor' objects..
And see how I parsed the doctorList.
doctorList: json['doctorList'] != null
? (json['doctorList'] as List).map((i) => Doctor.fromMap(i)).toList()
: null,
You may wonder, how the Doctor class may look like. Here you go
class Doctor {
final String doCode;
final String doctorName;
Doctor({this.doCode, this.doctorName});
factory Doctor.fromMap(Map<String, dynamic> json) {
return Doctor(
doCode: json['doCode'],
doctorName: json['doctorName'],
);
}
Map<String, dynamic> toMap() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['doCode'] = this.doCode;
data['doctorName'] = this.doctorName;
return data;
}
}
That's all. Hope you got the idea. Cheers!
I am returning multiple records as JSON and need to fill an object with them. How is done in Dart?
HomeCategory(0, Icons.check, Colors.blue[800], "Check In", [Task(0, "Check In", true),]),
The JSON result has all this data.
Deserialize the JSON string into a map:
import 'dart:convert';
...
Map<String, dynamic> jsonObj = json.decode(jsonString);
Then create a factory constructor for your class that converts the map into your object:
class HomeCategory {
final int id;
final String iconCode;
final String colorCode;
final String message;
final List<Task> tasks;
HomeCategory(
this.id,
this.iconCode,
this.colorCode,
this.message,
this.tasks,
);
HomeCategory.fromJson(Map<String, dynamic> jsonObj) {
int id = jsonObj['id'];
String iconCode = jsonObj['iconCode'];
String colorCode = jsonObj['colorCode'];
String message = jsonObj['message'];
List<Task> tasks = [];
var tasksObj = jsonObj['tasks'];
if (tasksObj != null && tasksObj is List) {
tasks = tasksObj.map((taskObj) => Task.fromJson(taskObj)).toList();
}
return HomeCategory(id, iconCode, colorCode, message, tasks);
}
Tailor the above code to the structure of your HomeCategory and Task classes as well as the structure of your JSON. (You're going to need to give the Task class a fromJson constructor as well, of course.)
EDIT: If your incoming JSON object is a list, you can simply change how you use the deserialized json object:
List<dynamic> jsonList = json.decode(jsonString);
List<HomeCategory> homeCategories = jsonList.map((jsonObj) => HomeCategory.fromJson(jsonObj)).toList();