I'm new to flutter,
My project work when I don't use my class but I want to use class so I change my project for use that and I have some problems.
In my code how to check if the parameter that I use in my function as KeyReference exist in my class ?
And how to use my parameter keyReference for search in my list of user ?
This is my class :
class User{
int type;
String name;
num index;
User({
this.type,
this.name,
this.index,
});
User.fromJson(Map<String, dynamic> map){
type = map['type'];
distance = map['name'];
hausse = map['index'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['type'] = this.type;
data['distance'] = this.name;
data['hausse'] = this.index;
}
And this is my function :
static List<User> getListItemsEquality(var value, String keyReference, List<User> items)
{
//**************** Error ****************//
if(items == null)
{
throw MyException.noData();
}
items.forEach((item) {
// =================================================================================
// I have an error on this The method 'containsKey' isn't defined for the type 'User'.
//=================================================================================
if(!item.containsKey(keyReference)){
throw MyException.parameterNotExist();
}
});
//**************** Script ****************//
// =================================================================================
// The getter 'keyReference' isn't defined for the type 'Charge'.
//=================================================================================
return items.where((c) => (c.keyReference == value)).toList();
}
Related
I am kind of new to flutter and working on the application where I need to save data locally to use it later when user will be offline.
I have a modal class with multiple inner classes:
Modal Class:
import 'package:hive/hive.dart';
part 'DownloadResponse.g.dart';
#HiveType(typeId: 1)
class DownloadResponse extends HiveObject {
#HiveField(0)
UserInfo userInfo;
#HiveField(1)
AppSetting appSetting;
#HiveField(2)
List<Seals> seals;
#HiveField(3)
String success;
#HiveField(4)
String message;
DownloadResponse(
{this.userInfo, this.appSetting, this.seals, this.success, this.message});
DownloadResponse.fromJson(Map<String, dynamic> json) {
userInfo = json['userInfo'] != null
? new UserInfo.fromJson(json['userInfo'])
: null;
appSetting = json['appSetting'] != null
? new AppSetting.fromJson(json['appSetting'])
: null;
if (json['seals'] != null) {
seals = new List<Seals>();
json['seals'].forEach((v) {
seals.add(new Seals.fromJson(v));
});
}
success = json['success'];
message = json['message'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.userInfo != null) {
data['userInfo'] = this.userInfo.toJson();
}
if (this.appSetting != null) {
data['appSetting'] = this.appSetting.toJson();
}
if (this.seals != null) {
data['seals'] = this.seals.map((v) => v.toJson()).toList();
}
data['success'] = this.success;
data['message'] = this.message;
return data;
}
}
#HiveType(typeId: 2)
class UserInfo extends HiveObject {
String fullName;
String mobileLastSyncDate;
UserInfo({this.fullName, this.mobileLastSyncDate});
UserInfo.fromJson(Map<String, dynamic> json) {
fullName = json['full_name'];
mobileLastSyncDate = json['mobile_last_sync_date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['full_name'] = this.fullName;
data['mobile_last_sync_date'] = this.mobileLastSyncDate;
return data;
}
}
#HiveType(typeId: 3)
class AppSetting extends HiveObject {
String appWebviewHeight;
String appScreenHeaderSealScan;
String appScreenHeaderSealInfo;
String appScreenHeaderPicture1;
String appScreenHeaderPicture2;
AppSetting(
{this.appWebviewHeight,
this.appScreenHeaderSealScan,
this.appScreenHeaderSealInfo,
this.appScreenHeaderPicture1,
this.appScreenHeaderPicture2});
AppSetting.fromJson(Map<String, dynamic> json) {
appWebviewHeight = json['app_webview_height'];
appScreenHeaderSealScan = json['app_screen_header_seal_scan'];
appScreenHeaderSealInfo = json['app_screen_header_seal_info'];
appScreenHeaderPicture1 = json['app_screen_header_picture_1'];
appScreenHeaderPicture2 = json['app_screen_header_picture_2'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['app_webview_height'] = this.appWebviewHeight;
data['app_screen_header_seal_scan'] = this.appScreenHeaderSealScan;
data['app_screen_header_seal_info'] = this.appScreenHeaderSealInfo;
data['app_screen_header_picture_1'] = this.appScreenHeaderPicture1;
data['app_screen_header_picture_2'] = this.appScreenHeaderPicture2;
return data;
}
}
#HiveType(typeId: 4)
class Seals extends HiveObject {
String sealId;
String sealHtml;
List<Documents> documents;
Seals({this.sealId, this.sealHtml, this.documents});
Seals.fromJson(Map<String, dynamic> json) {
sealId = json['seal_id'];
sealHtml = json['seal_html'];
if (json['documents'] != null) {
documents = new List<Documents>();
json['documents'].forEach((v) {
documents.add(new Documents.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['seal_id'] = this.sealId;
data['seal_html'] = this.sealHtml;
if (this.documents != null) {
data['documents'] = this.documents.map((v) => v.toJson()).toList();
}
return data;
}
}
#HiveType(typeId: 5)
class Documents extends HiveObject {
String documentId;
String documentName;
String documentLink;
Documents({this.documentId, this.documentName, this.documentLink});
Documents.fromJson(Map<String, dynamic> json) {
documentId = json['document_id'];
documentName = json['document_name'];
documentLink = json['document_link'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['document_id'] = this.documentId;
data['document_name'] = this.documentName;
data['document_link'] = this.documentLink;
return data;
}
}
And this is my logic where I am trying to save data in the hive:
// We get the current app directory
WidgetsFlutterBinding.ensureInitialized();
final appDocDir = await getApplicationDocumentsDirectory();
// We initialize Hive and we give him the current path
Hive
..init(appDocDir.path)
..registerAdapter(DownloadResponseAdapter());
var box = await Hive.openBox('driverData');
//box.put('ew32', DownloadResponse('BMW','test', 2002));
UserInfo userInfo = downloadResponse.userInfo;
AppSetting appSetting = downloadResponse.appSetting;
List<Seals> sealList = downloadResponse.seals;
String success = downloadResponse.success;
String message = downloadResponse.message;
await box.put('driverData', DownloadResponse()
..userInfo = userInfo
..appSetting = appSetting
..seals = sealList
..success = success
..message = message);
print(box.get('driverData'));
I get this exception when box.put() runs:
Unhandled Exception: HiveError: Cannot write, unknown type: UserInfo. Did you forget to register an adapter
My question is how do I create and add multiple adapters with hive as my modal class has multiple classes?
I got the answer of the same. You will have all the adapters available in the automated generated file.
You just need to add them before saving data like this:
Hive
..init(appDocDir.path)
..registerAdapter(DownloadResponseAdapter())
..registerAdapter(UserInfoAdapter())
..registerAdapter(AppSettingAdapter())
..registerAdapter(SealsAdapter())
..registerAdapter(DocumentsAdapter()
);
My code works but I want to update this with objects. But I don't see how to add a property value to an object. It must be declared in the constructor ??
For exemple I have a user object with some property.
But in my code I need to classify users by those with the closest salary to a certain value.
For that I want to add an index key which I then use to organize them in order.
This key is just used to classify my users to have the order I want
This index key is not base defined in my object.
My class user :
class Users{
List<User> user;
Users({this.user});
Users.fromJson(Map<String, dynamic> json) {
if (json['user'] != null) {
user= new List<User>();
json['user'].forEach((v) {
user.add(new User.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.user!= null) {
data['user'] = this.user.map((v) => v.toJson()).toList();
}
return data;
}
#override
String toString() {
return '{${this.user}}';
}
}
class User{
String name;
int gender;
num salary;
User(
{this.name,
this.gender,
this.salary,
});
User.fromJson(Map<String, dynamic> json) {
name= json['name'];
gender= json['gender'];
salary= json['salary'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['gender'] = this.gender;
data['salary'] = this.salary;
return data;
}
#override
String toString() {
return '{ '
'${this.name},'
'${this.gender},'
'${this.salary},'
'}';
}
void add(String key, dynamic value) {
// ... implementation
}
}
Here an exemple of the function the classify my user and adding the index key in a functions.dart file
List<User> func_orderedItemByClosestSalary(List<User> filteredUsers)
{
switch (filteredUsers.length)
{
case 1:
// One result
print('un seul resultat ...');
filteredUsers[0].index = 0; // Not work for adding the index key
break;
The reason why filteredUsers[0].index = 0; doesn't work is because index isn't defined on Users object. Add index on Users to be able to update its value.
class User{
int index;
String name;
int gender;
num salary;
...
}
I'm new to flutter and despite my research I can't find the answers. How to update the values of a class according to a dynamic variable.
For example in my User class I want to update the salary of my User according to a map. How to call the key to update the class ?
My class :
class Users{
List<User> user;
Users({this.user});
Users.fromJson(Map<String, dynamic> json) {
if (json['user'] != null) {
user= new List<User>();
json['user'].forEach((v) {
user.add(new User.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.user!= null) {
data['user'] = this.user.map((v) => v.toJson()).toList();
}
return data;
}
#override
String toString() {
return '{${this.user}}';
}
}
class User{
String name;
int gender;
num salary;
User(
{this.name,
this.gender,
this.salary,
});
User.fromJson(Map<String, dynamic> json) {
name= json['name'];
gender= json['gender'];
salary= json['salary'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['gender'] = this.gender;
data['salary'] = this.salary;
return data;
}
#override
String toString() {
return '{ '
'${this.name},'
'${this.gender},'
'${this.salary},'
'}';
}
}
Here the function that calculate the new salary of my User and update this.
func_OrderedUsers(List<User> users)
{
List<User> _UsersInOrder;
if (users.length > 0)
{
users.forEach((user)
{
Map _params = {
"salary" : func_CalculateNewSalary(user)
};
func_UpdateItem(user, _params);
});
//... some code
}
And My function UpdateItem :
func_UpdateItem(var item, Map params)
{
if(params != null){
params.forEach((key, value)
{
if(value != null){
// Here is my problem !
// How to use the key variable ?
item.salary = value; // If I write directly the parameter it works (salary)
}
});
}
return item;
}
What you're trying to do is something that dart:mirrors would do. However, since you seem to be using flutter, this is not available for you to use.
Instead you'll have to manually map each key of your Map to a field in your object, just like in your fromJson constructor. You could add a method that does this within your class. Ex.
void updateFieldsFromMap(Map<String, dynamic> input) {
if(input['name'] != null) name = input['name'];
if(input['gender'] != null) gender = input['gender'];
if(input['salary'] != null) salary = input['salary'];
}
You can try to use factory
factory User.fromJson(Map<String, dynamic> json) {
return new User(
name: data['name'],
gender: data['gender'],
salary: data['salary'],
);
}
I've been wrapping my head around this issue for the past 2 hours (keep in mind that I'm new to Flutter). I'm trying to check if I've set up everything properly for getting a movie list from OMDB. Everything seems okay except the fact that I don't know how to access something inside a list ie. originalTitle.
This is the model:
class MovieItem {
int page;
int totalResults;
int totalPages;
List<Results> results;
MovieItem({this.page, this.totalResults, this.totalPages, this.results});
MovieItem.fromJson(Map<String, dynamic> json) {
page = json['page'];
totalResults = json['total_results'];
totalPages = json['total_pages'];
if (json['results'] != null) {
results = new List<Results>();
json['results'].forEach((v) {
results.add(new Results.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['page'] = this.page;
data['total_results'] = this.totalResults;
data['total_pages'] = this.totalPages;
if (this.results != null) {
data['results'] = this.results.map((v) => v.toJson()).toList();
}
return data;
}
}
class Results {
String posterPath;
int id;
String originalLanguage;
String originalTitle;
String title;
Results(
{this.posterPath,
this.id,
this.originalLanguage,
this.originalTitle,
this.title,});
Results.fromJson(Map<String, dynamic> json) {
posterPath = json['poster_path'];
id = json['id'];
originalLanguage = json['original_language'];
originalTitle = json['original_title'];
title = json['title'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['poster_path'] = this.posterPath;
data['id'] = this.id;
data['original_language'] = this.originalLanguage;
data['original_title'] = this.originalTitle;
data['title'] = this.title;
return data;
}
}
You are attempting to call a property on a List<Result> instead of Result. The property you are attempting to access exists on Result ... if there is a List of Result objects, what do you expect to return with movieItem.results.originalTitle? There could be any number of Result object with possibly different titles? If you just want to print them all out:
Future<MovieItem> movieItem() async {
var movieItem = await
client.movieItem();
movieItem.results.forEach((result) => print(result.originalTitle));
return movieItem;
}
The forEach will allow you to call the property and print it on every Result in the list
Your movieItem model class has list of result objects. So when you call the client.movieItem method the you get a MovieItem Object, and it you want to print the specific result item then just do this
print(movieItem.results[0].originalTitle)
and if you want to access all the objects from the result list then using for loop you can achieve it
for(int i=0;i<movieItem.results.length;i++)
{
print(movieItem.results[i].originalTitle);
}
I have created multiple models and using json_serialization
Example Company and Employee and many more.
import 'package:json_annotation/json_annotation.dart';
part 'company.g.dart';
#JsonSerializable()
class Company {
Company({this.id, this.name});
String id;
String name;
factory Company.fromJson(Map<String, dynamic> json) => _$CompanyFromJson(json);
Map<String, dynamic> toJson() => _$CompanyToJson(this);
}
import 'package:json_annotation/json_annotation.dart';
part 'employee.g.dart';
#JsonSerializable()
class Employee {
Employee({this.id, this.name, this.email, this.phone, this.photo});
String id;
String name;
String email;
String phone;
String photo;
factory Employee.fromJson(Map<String, dynamic> json) => _$EmployeeFromJson(json);
Map<String, dynamic> toJson() => _$EmployeeToJson(this);
}
Now I want to create a reusable service that can return Stream with type Company, Employee or other types.
I'm using Firebase so the return type is Map.
example service class
class BaseService<T> {
final String collection;
CollectionReference _collectionRef;
FirebaseBase({#required this.collection}) {
_collectionRef = Firestore.instance.collection(collection);
}
Stream<List<T>> find() {
return inColRef.snapshots().map((list) {
return list.documents.map((doc) {
final Map<String, dynamic> data = doc.data;
data['id'] = doc.documentID;
return data;
}).toList();
});
}
}
How do I convert the return data (Map) to a type Company or Employee.
Those class can use the factory of fromJson(data).
But I can't return a T.fromJson(data).
I would like to get
Stream<List<Company>> companies = ServiceBase('companies').find();
Stream<List<Employee>> employees = ServiceBase('employee').find();
This is how you would accomplish the generic assignment using your current code:
class BaseService<T> {
final String collection;
CollectionReference _collectionRef;
FirebaseBase({#required this.collection}) {
_collectionRef = Firestore.instance.collection(collection);
}
Stream<List<T>> find() {
return inColRef.snapshots().map((list) {
return list.documents.map((doc) {
final Map<String, dynamic> data = doc.data;
data['id'] = doc.documentID;
return _build(data) as T;
}).toList();
});
}
dynamic _build(final Map<String, dynamic> data) {
if(collection == 'companies') {
return Company.fromJson(data);
} else if(collection == 'employee') {
return Employee.fromJson(data);
}
... throw if invalid collection passed ? ...
}
}
This would be called as so:
Stream<List<Company>> companies = BaseService<Company>('companies').find();
Stream<List<Employee>> employees = BaseService<Employee>('employee').find();
I would recommend that you should a different object structure with the template method pattern such as:
class CompanyService extends BaseService<Company> {
CompanyService() : super('companies');
Company build(final Map<String, dynamic> data) => Company.fromJson(data);
}
class EmployeeService extends BaseService<Employee> {
EmployeeService() : super('employee');
Employee build(final Map<String, dynamic> data) => Employee.fromJson(data);
}
abstract class BaseService<T> {
final String collection;
CollectionReference _collectionRef;
BaseService(this.collection) {
_collectionRef = Firestore.instance.collection(collection);
}
T build(final Map<String, dynamic> data);
Stream<List<T>> find() {
return inColRef.snapshots().map((list) {
return list.documents.map((doc) {
final Map<String, dynamic> data = doc.data;
data['id'] = doc.documentID;
return build(data);
}).toList();
});
}
}
which would result in the calling code looking something like this:
Stream<List<Company>> companies = CompanyService().find();
Stream<List<Employee>> employees = EmployeeService().find();