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;
...
}
Related
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();
}
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'],
);
}
In my Home.dart
static _getList() async {
Network network = Network();
final List list = await network.getData();
print("jsonString");
print(list);
return list;
}
Result in console:
flutter: [{id: 1, calc: 000100, name: Test, date: 2018-03-29 12:45:26.9830000}]
I need to get the id's and names of this object and generate a list, to be read
You need to convert your json data to objects.
There are tools to help you generating object from json like json2Dart. The result is :
class MyObject {
int id;
String calc;
String name;
String date;
MyObject({this.id, this.calc, this.name, this.date});
MyObject.fromJson(Map<String, dynamic> json) {
id = json['id'];
calc = json['calc'];
name = json['name'];
date = json['date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['calc'] = this.calc;
data['name'] = this.name;
data['date'] = this.date;
return data;
}
#override
String toString() {
return '$id';
}
}
You need to iterate over your list from getData() and call MyObject.fromJson() from each occurence :
var myObjetcs = [];
for (var item in list) {
myObjetcs.add(MyObject.fromJson(item));
}
//Now, do what you want with myObjects
Hope it will help you
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();