Is it possible to make an Array of Objects in Dart/Flutter - flutter

Hello I am wondering if it is possible to make an array of objects in dart/flutter.
class Student {
int math;
}
Student[] studentArray = new
Student[7];
studentArray[0] = new Student();

void main() {
List persons = [User("foo"), User("bar")]; //non-empty on create
List users = []; //blank initially
for (int i = 0; i < 5; i++) {
users.add("User $i");
}
//print using iterator
for (var u in users) {
print(u);
}
/*
* first element can be accessed using users[0] or users.first
* last element can be accessed using users.last
* */
}
class User {
String name;
User(this.name);
}

Sure thing
import 'dart:collection';
class MyClass {
List<MyObjectClass> myList = [];
}

To make array of objects in dart we have List.
In your scenario to get array of Student type objects we define List of type student and add the objects of student inside the List. Below is the sample example code of adding Student objects into a List.
List<Student > StudentDetails = [new Student (),new Student ()];
for more information about how to add objects into list refer to the link
https://kodeazy.com/flutter-array-userdefined-class-objects/

Related

Dart list added to another list becomes empty when emptying the first list

I have the below user defined objects -
class PhoneBookContact {
String? phoneBookContact;
List<ContactNumber>? contactNumbers;
PhoneBookContact(this.phoneBookContact, this.contactNumbers);
}
class ContactNumber {
String phone;
bool availableOnBol;
ContactNumber(this.phone, this.availableOnBol);
}
In my main method I am creating a list for the ContactNumber class and then later adding that ContactNumber list to the contactNumbers property of PhoneBookContact list. This is all done inside of a for loop.
The issue I am having is when I am clearing the contactNumbers list after adding those items to the contactNumbers property of the PhoneBookContact list, I see those cleared from the PhoneBookContact list as well, which I find weird, or maybe I am not thinking it the right way.
List<PhoneBookContact> phoneBookContacts = [];
List<ContactNumber> contactNumbers = [];
for (var contact in contacts) {
contactNumbers.clear();
if (contact.phones.isNotEmpty) {
for (var phone in contact.phones) {
if (true) {
contactNumbers.add(ContactNumber(phone.number, true));
} else {
contactNumbers.add(ContactNumber(phone.number, false));
}
}
}
phoneBookContacts
.add(PhoneBookContact(contact.displayName, contactNumbers));
}
Your PhoneBookContact constructor does not make a copy of the list. It takes a reference to the list and remembers it.
Since you clear the list every loop but reuse the same list instance, all your PhoneBookContacts will have the same list.
Lets clean up your method a little:
List<PhoneBookContact> phoneBookContacts = [];
for (var contact in contacts) {
List<ContactNumber> contactNumbers = [];
for (var phone in contact.phones) {
final condition = true; // should be your complicated expression
contactNumbers.add(ContactNumber(phone.number, condition));
}
phoneBookContacts.add(PhoneBookContact(contact.displayName, contactNumbers));
}
Apart from removing some clutter, it makes sure that each loop, you instantiate a new list so that each PhoneBookContact has it's own list.

Duplicate Array list value automatically changed in Flutter

I'm very surprised after this issue. First, inform all things I have used in my project.
I have used Getx in my project. I have called the API using the Getx controller file.
Below code used in getx controller file. "PLTimeSlotModel" is model and. it has two params (name, isselect).
var futureTimeSlot_PL_C_D = Future.value(<PLTimeSlotModel>[]).obs;
callTimeSlotAPI() async {
futureTimeSlot_PL_C_D.value = FetchTimeSlotList();
}
Future<List<PLTimeSlotModel>> FetchTimeSlotList() async {
// Fetching data with API calling
}
Screen A:
List<PLTimeSlotModel> listA = [];
List<PLTimeSlotModel> listB = [];
#override
void initState() {
super.initState();
_plController.callTimeSlotAPI();
}
Another method is to create two lists using the future list:
List<PLTimeSlotModel> temp1 = await _plController.futureTimeSlot_PL_C_D.value;
temp1.forEach((element) {
listA.add(element);
listB.add(element);
});
onclick:
for(int i =0;i<listA.length;i++){
listA[i].isselect = false;
print(listA[i].isselect);
print(listB[i].isselect);
}
Now the issue is I have changed/updated the only "listA" value, So why automatically set the same value to "listB"? The two list is based on the one list.
A List in Dart contains references objects, not the objects themselves. So what you are doing is copying references to objects into two lists. But since they are pointing at the same objects, you will see any modification in one list also happen in the other list. You need to copy each PLTimeSlotModel object and put the copy into your new list.
One way to copy objects is to create an constructor which takes an object of the same type and creates a new object based on this first object. So something like this:
class Person {
String name;
Person(this.name);
Person.fromPerson(Person other) : this(other.name);
#override
String toString() => 'Person($name)';
}
void main() {
final persons = [
Person('Adam'),
Person('Bob'),
];
// Make new list based on persons
final otherPersonList = [
...persons.map((person) => Person.fromPerson(person))
];
otherPersonList[0].name = 'Carl';
print(persons); // [Person(Adam), Person(Bob)]
print(otherPersonList); // [Person(Carl), Person(Bob)]
}

flutter/dart static list or list of singleton object always return it's default values when calling it from another class

i am trying to use static list as global variable that can be accessible through all the dart classes , so i have done like that:
class MyData {
// initialize it to an empty list
static var List<MyObject> myObjectList = new List<MyObject>();
}
then in another class I load that empty list with list of MyObject (no doubt that it loaded with success)
I do add objects to that list , the list will not remain empty !!
when it comes the time to use the myObjectList in another class it returns an empty list with 0 length
class SomeClass {
.....
void getMyObjectsList(){
.....
// this display 0 length and has no data
print("my static object list length == ${MyData.myObjectList.length}");
}
}
i have also tried using a singleton instance and it return the same result :
class MyData {
static final MyData _singleton = MyData._internal();
factory MyData() {
return _singleton;
}
MyData._internal();
// object property
var List<MyObject> myObjectList = new List<MyObject>();
}
well this also return the default value which is an empty list:
class SomeClass {
.....
void getMyObjectsList(){
....
// this display 0 length and has no data
print("my singleton object list length == ${MyData().myObjectList.length}");
}
}
I think you missed to Store/Copy/Add objects in the List
class MyData {
// initialize it to an empty list
static List<MyObject> myObjectList = [];
}
Add some Objects to List before accessing the List
class SomeClass {
.....
/// Add Object to List using this Method
void addDataToList(MyObject data){
myObjectList.add(data);
}
void getMyObjectsList(){
.....
// this display 0 length and has no data
print("my static object list length == ${MyData.myObjectList.length}");
}
}
Note : if there is no Data list will return 0
so please add some data before using the .length() on List.
Hope this Solve your Issue
the problem was not in the static list , it was inside the TextField onTap event ,
i was using the static list inside it so i tried to use a local variable and i faced the same problem , the variable return the default value always.

How can I combine multiple objects based on the same value they have in Dart?

class Item{
var name;
var productId;
Item(this.name,this.productId);
}
class Price{
List<String> listOfProductIds = [];
double amount;
}
Lets say I have list of prices:
[["productid1","productid3"], 199.00], ["productid2","productid4"],299.00],...);
I have TWO different lists.
This one:
[["myName","productid1"],["myNamee","productid2"]]
And, this one:
[["myName","productid3"],["myNamee","productid4"]]
for example, I want to retrieve items for a price of 199.00. basically I want to show ["myName","productid1"] and ["myName","productid3"] How can I achieve this?
As far as I know this is a custom use case and this cannot be done with a single statement in Dart. However, this result can be achieved with the help of the forEach loop in Dart.
Here is a minimal example reproducing your above problem -
class Prices {
List<String> products;
double price;
Prices(this.products, this.price);
}
void main() {
List<Prices> priceList = [Prices(["productid1","productid3"], 199.00), Prices(["productid2","productid4"],299.00)];
List<List<String>> productList1 = [["myName","productid1"],["myNamee","productid2"]];
List<List<String>> productList2 = [["myName","productid3"],["myNamee","productid4"]];
List<List<String>> resultList = List();
List<String> comparatorList = priceList.singleWhere((priceObj) => priceObj.price == 199.0).products;
productList1.forEach((product) {
if(comparatorList.contains(product[1])) {
resultList.add(product);
}
});
productList2.forEach((product) {
if(comparatorList.contains(product[1])) {
resultList.add(product);
}
});
print(resultList.toString());
//Above statement prints [[myName, productid1], [myName, productid3]]
}
In the above example first we create the comparatorList which contains the names of only those products which are priced at 199.0.
Then, we extract only those items from both the product lists which are present in the comparatorList as well. Hope this helps!
This is what I have done to overcome the issue:
Item tempOne,tempTwo;
for(int i=0; i<prices.listOfProductIds.length;i++){
for(int j=0; j<itemOne.length; j++){
if((prices.listOfProductIds[i]) == (itemOne.productId)){
tempOne = itemOne;
break;
}
}
for(int j=0; j<itemTwo.length; j++){
if((prices.listOfProductIds[i]) == (itemTwo.productId)){
tempTwo = itemTwo;
break;
}
}
Wrapper finalResult = new Wrapper(tempOne,tempTwo,prices[i]);
}
Defined wrapper class
class Wrapper{
Item itemOne,itemTwo;
Price price
Warpper(this.itemOne,this.itemTwo,this.price)
}

Extending base List class with extra functionality in Dart language

This question is about Dart language.
I want to have a class which is just a List but with some extra functionality.
For example I have a class named Model:
class Model{
String name;
int type;
Model(this.name, this.type);
}
I know that Model's type could take only four values: from 0 to 3.
And I want to have a method, which can give me a List of Models of specified type, e.g. List<Model> modelCollection.getByType(int type);.
I plan to to have four 'hidden' Lists of the Models (grouped by type) in that class.
Thus I need to override addition and removal of List elements to make that hidden lists being up to date.
How can I realize this as easy as possible?
P.S. I know this is quite simple, but I'm poorly familiar with Object inheritance and can't find proper examples.
P.P.S. I've also checked this but don't know is it outdated or not and didn't catch the idea.
To make a class implement List there are several ways :
Extending ListBase and implementing length, operator[], operator[]= and length= :
import 'dart:collection';
class MyCustomList<E> extends ListBase<E> {
final List<E> l = [];
MyCustomList();
void set length(int newLength) { l.length = newLength; }
int get length => l.length;
E operator [](int index) => l[index];
void operator []=(int index, E value) { l[index] = value; }
// your custom methods
}
Mixin ListMixin and implementing length, operator[], operator[]= and length= :
import 'dart:collection';
class MyCustomList<E> extends Base with ListMixin<E> {
final List<E> l = [];
MyCustomList();
void set length(int newLength) { l.length = newLength; }
int get length => l.length;
E operator [](int index) => l[index];
void operator []=(int index, E value) { l[index] = value; }
// your custom methods
}
Delegating to an other List with DelegatingList from the quiver package:
import 'package:quiver/collection.dart';
class MyCustomList<E> extends DelegatingList<E> {
final List<E> _l = [];
List<E> get delegate => _l;
// your custom methods
}
Depending on your code each of those options have their advantages. If you wrap/delegate an existing list you should use the last option. Otherwise use one of the two first options depending on your type hierarchy (mixin allowing to extend an other Object).
A basic approach is to extend an Object with IterableMixin. It also seems that you don't even need to override the "length" getter or let's say all methods that the IterableMixin already provides.
import 'dart:collection';
class Model {
String name;
int type;
Model(this.name, this.type) {
}
}
class ModelCollection extends Object with IterableMixin {
List<Model> _models;
Iterator get iterator => _models.iterator;
ModelCollection() {
this._models = new List<Model>();
}
//get one or the first type
Model elementByType(int type) {
for (Model model in _models) {
if (model.type == type) {
return model;
}
}
}
//get all of the same type
List<Model> elementsByType(int type) {
List<Model> newModel = new List<Model>();
for (Model model in _models) {
if (model.type == type) {
newModel.add(model);
}
}
return newModel;
}
add(Model model) {
this._models.add(model);
}
}
Excuse my strong static typing.
You might be interested in quiver.dart's Multimap. It behaves like a Map that allows multiple values per key.
Here's the code on github: https://github.com/google/quiver-dart/blob/master/lib/src/collection/multimap.dart#L20
It's on pub simply as quiver. We'll be hosting the dartdocs somewhere soon.