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

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)
}

Related

How to make model fields observable in Flutter

I have a model called category , which has two fields, User has a list of categories and what to update the category name, for State Management getx is used
class Category {
String? categoryName;
bool status;
Category(this.categoryName,this.status);
}
I have a observable list called catList which is used in List widget
var catList = <Category>[].obs;
when I update the category field it doest not update
catList[index].categoryName = categoryChangedName.value;
but If I update the item in object and then assign the object to catList then It changed
catList[index] = Category(categoryChangedName.value, catList[index].status );
My question is how to make model fields observable, if we have more fields changes then this is not proper way.
As of GetX documentation you need to update values using method and call update(); method inside custom object !
Ex:
class Controller extends GetxController {
int counter = 0;
void increment() {
counter++;
update(); // look here!
}
}
Your use case might be like....
class Category {
String? categoryName;
bool status;
Category(this.categoryName,this.status);
void updateCategoryName(name){
this.categoryName = name;
update();
}
}
//Use like..
catList[index].updateCaetgoryName = categoryChangedName.value;

How to copy a list into another in a StateNotifier, so it update with every change

The List EleccionSinSeleccionClase is just a list of a class who has a String on it.
class EleccionSinSeleccionClase {
String Eleccion;
}
The state List is another class:
class EleccionConSleccionClase {
String Eleccion;
bool selec;
}
The problem is that I want to copy the first into the state of the StateNotifier, this line break the code.
This is the line: state[i].Eleccion = ListaElecciones[i].Eleccion;
class EleccionesConSeleccionNotifier
extends StateNotifier<List<EleccionConSleccionClase>> {
final List<EleccionSinSeleccionClase> ListaElecciones;
EleccionesConSeleccionNotifier({required this.ListaElecciones}) : super([]);
void init(){
print(ListaElecciones.length.toString());
if(ListaElecciones.length != 0){
for (int i = 0; i < ListaElecciones.length; i++) {
state[i].Eleccion = ListaElecciones[i].Eleccion; ////HERE////
}
}
}
}
final eleccionConSleccionStateNotifierProvider = StateNotifierProvider<
EleccionesConSeleccionNotifier, List<EleccionConSleccionClase>>((ref) {
final eleccioneswatch =
ref.watch(eleccionesSinSeleccionStateNotifierProvider);
return EleccionesConSeleccionNotifier(ListaElecciones: eleccioneswatch)..init();
});
Maybe the problem is that you initialize state as an empty list super([]) and then you're trying to change a value in an index that doesn't exist (state[i] where the list is obviously empty and cannot access that position)
void init(){
print(ListaElecciones.length.toString());
if(ListaElecciones.length != 0){
/// you will need to check if both lists are the same lenght if you actually want to do this
/// without failling
/*for (int i = 0; i < ListaElecciones.length; i++) {
state[i].Eleccion = ListaElecciones[i].Eleccion; ////HERE////
}*/
/// if you only want to copy Eleccion parameter in a new class this would be the easiest way
state = ListaElecciones.map((cb) => EleccionConSleccionClase(Eleccion: cb.Eleccion)).toList();
}
}

How to observe ObservableList item properties changes

I'm building a shopping app in Flutter using MVC pattern and mobx for app state management.
At the moment, I have a mobx store for cart items and one store for the cart controller.
The cart controller has a ObservableList of cart items and problem is that I don't know if there's a way of observing changes on cart items.
For instance, I'd like to observe cartItem.title or cartItem.total.
Is there a way to track this with ObservableList?
And whats is .observe() method the observable list has? (Think the documentation wasn't clear for me)
UPDATE: SAMPLE CODE
As I said I have to mobx sotres, one for the cart item and for the cart itself.
In the cart item store:
import 'package:mobx/mobx.dart';
part 'cart-item.model.g.dart';
class CartItemModel = _CartItemModel with _$CartItemModel;
abstract class _CartItemModel with Store {
int id;
String title;
String price;
String description;
#observable
int _quantity = 0;
#observable
double _total = 0;
_CartItemModel({
this.id,
this.title,
this.price,
this.description,
}) {
reaction(
(_) => _quantity,
(quantity) {
getTotal();
},
);
}
getItemQuantity() => _quantity.toString(); // Return item quantity
#action
increase() {
// Increase item quantity
if (_quantity <= 99) {
_quantity++;
}
}
#action
decrease() {
// Decrease item quantity
if (_quantity > 0) {
_quantity--;
}
}
#action
getTotal() {
// Return total price by item quantity
_total = double.parse(price) * _quantity;
return _total.toString();
}
}
And then in the cart controller:
import 'package:faccioo_user_app/models/cart-item.model.dart';
import 'package:mobx/mobx.dart';
part 'cart.controller.g.dart';
class CartController = _CartController with _$CartController;
abstract class _CartController with Store {
#observable
ObservableList<CartItemModel> cartItems = ObservableList<CartItemModel>();
#action
addItem(CartItemModel item) {
cartItems.insert(0, (item));
item.increase();
}
#action
removeItem(CartItemModel item) {
cartItems.removeWhere((cartItem) => cartItem.id == item.id);
getTotal();
}
#action
getSubtotal() {
cartItems.forEach((item) {
subtotal = subtotal + double.parse(item.getTotal());
});
return subtotal.toString();
}
#action
getTotal() {
total = (subtotal + shippingFee + serviceFee + change) - discount;
return total.toString();
}
}
The view is not being notified by the changes in cartItem.total, for example?. How do I observe changes in cartItemModel.total from ObservableLis?
To be more clear I got this print in which we can see that cart item quantity and total increase, therefore CartItemModel reactivity is working fine, but the cart controller can't track those changes from ObservableList, then the controller is not updating the view.
I'd really appreciate links and references from where I can learn more about mobx with Flutter and observable lists.
Cart view with cart item
this is an old question but I will share the hints for the solution and how to improve it.
You don't need to create a store for the model, just wrap the properties with #observable, #computed, etc.
Actions are meant to write to the store and update the store properties. If you want to read properties, just write a simple get property without the #action annotation, or if you want to read a property based on other #observable properties, use the get with #computed.
The store should be only the CartController in which you should have a #computed property that will change based on other properties changes, e.g. for the CartController store:
The CartItemModel should be transformed into a simple data class with getters and setters and is the store that will manage its state.
I didn't check in terms of types .. etc.., the getters are missing the return types, only the setters that don't need return type.
#computed
double get total() => subtotal + shippingFee + serviceFee + change - discount;
#computed
double get subtotal() {
double subTotalAggregator = 0;
cartItems.forEach((item) {
subTotalAggregator += double.parse(item.getTotal());
});
return subTotalAggregator;
}

Using List to store and find class element with random member variable

I want to store a class in a List to later retrieve the value. Now the problem I
m having is that one of the members is a random value. So when trying to retrieve the entry I can't find it, since I can't produce the 'key'.
I'm happy for suggestions on implementing this in a different way.
So this is the example class I want to store in a list:
class MyDevice{
int device;
int randomNumber;
void set(int device, int random){
this.device = device;
this.randomNumber = random;
}
}
class Handling{
final List<MyDevice> myDevicesList = new List<MyDevice>();
...
...
MyDevice dev = new MyDevice();
dev.set(device, random);
//Store entry into List
myDevicesList.add(dev);
...
...
Now I want to delete or possibly replace an entry, but I will have no way of
finding it since the random value is not known after storing above.
// Note that I have the device value supplied in a call-back, for the sake of this
// example let's just define a method for removing
void removeEntry(int device){
MyDevice dev = new MyDevice();
dev.set(device, );
myDevicesList.remove(dev);
}
How can I find / remove an entry that is a class and I only want to 'search' the list with one of the embers in the class that is stored?
Is the only solution to walk the list and make my own compare method to identify the entry by the 'device' member?
All you need is the removeWhere List method. You have to remove where MyDevice.device matches the argument, device.
Here's the code you requested for
void removeEntry(device) {
myDevicesList.removeWhere((element) => element.device == device);
}
Here's the full code.
import 'dart:math';
class MyDevice {
int device;
int randomNumber;
void setValue(int device, int random) {
this.device = device;
this.randomNumber = random;
}
}
class Handling {
final List<MyDevice> myDevicesList = new List<MyDevice>();
void addToList(device, random) {
MyDevice dev = new MyDevice();
dev.setValue(device, random);
myDevicesList.add(dev);
}
void removeEntry(device) {
myDevicesList.removeWhere((element) => element.device == device);
}
List<MyDevice> get list {
return myDevicesList;
}
}
void main() {
final handle = new Handling();
handle.addToList(2, Random().nextInt(5));
handle.addToList(18, Random().nextInt(4));
handle.addToList(12, Random().nextInt(9));
print("List before ${handle.list.map((element) {
return [element.device, element.randomNumber];
})}");
handle.removeEntry(18);
print("List after ${handle.list.map((element) {
return [element.device, element.randomNumber];
})}");
}
The output is
List before ([2, 1], [18, 0], [12, 7])
List after ([2, 1], [12, 7])
Here's the solution on dartpad
You don't know random value, so you have to manually compare and remove item from list.
Following code may help you.
In following example i added 1,2 and 5 and remove 2 after that you can see in print only 1 and 5.
class MyDevice {
int device;
int randomNumber;
void set(int device, int random) {
this.device = device;
this.randomNumber = random;
}
}
class Delet2 extends StatefulWidget {
#override
_Delet2State createState() => _Delet2State();
}
class _Delet2State extends State<Delet2> {
final List<MyDevice> myDevicesList = new List<MyDevice>();
#override
void initState() {
super.initState();
add(1);
add(2);
add(5);
delete(2);
for (int k = 0; k < myDevicesList.length; k++) {
print(myDevicesList[k].device);
}
}
add(int number) {
MyDevice dev = new MyDevice();
dev.set(number, Random().nextInt(1000));
myDevicesList.add(dev);
}
delete(int number) {
for (int i = 0; i < myDevicesList.length; i++) {
if (myDevicesList[i].device == number) {
myDevicesList.removeAt(i);
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}

Is it possible to make an Array of Objects in Dart/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/